passt: Address gcc 11 warnings
A mix of unchecked return values, a missing permission mask for open(2) with O_CREAT, and some false positives from -Wstringop-overflow and -Wmaybe-uninitialized. Reported-by: Martin Hauke <mardnh@gmx.de> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
parent
087b5f4dbb
commit
1a563a0cbd
7 changed files with 91 additions and 33 deletions
14
Makefile
14
Makefile
|
@ -15,6 +15,20 @@ CFLAGS += -DPAGE_SIZE=$(shell getconf PAGE_SIZE)
|
|||
CFLAGS += -DNETNS_RUN_DIR=\"/run/netns\"
|
||||
CFLAGS += -DPASST_AUDIT_ARCH=AUDIT_ARCH_$(shell uname -m | tr [a-z] [A-Z])
|
||||
|
||||
# On gcc 11.2, with -O2 and -flto, tcp_hash() and siphash_20b(), if inlined,
|
||||
# seem to be hitting something similar to:
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78993
|
||||
# from the pointer arithmetic used from the tcp_tap_handler() path to get the
|
||||
# remote connection address.
|
||||
ifeq ($(shell $(CC) -dumpversion),11)
|
||||
ifneq (,$(filter -flto%,$(CFLAGS)))
|
||||
ifneq (,$(filter -O2,$(CFLAGS)))
|
||||
CFLAGS += -DTCP_HASH_NOINLINE
|
||||
CFLAGS += -DSIPHASH_20B_NOINLINE
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
prefix ?= /usr/local
|
||||
|
||||
all: passt pasta passt4netns qrap
|
||||
|
|
13
passt.c
13
passt.c
|
@ -257,13 +257,16 @@ static void pid_file(struct ctx *c) {
|
|||
if (!*c->pid_file)
|
||||
return;
|
||||
|
||||
pid_fd = open(c->pid_file, O_CREAT | O_WRONLY);
|
||||
pid_fd = open(c->pid_file, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
|
||||
if (pid_fd < 0)
|
||||
return;
|
||||
|
||||
n = snprintf(pid_buf, sizeof(pid_buf), "%i\n", getpid());
|
||||
|
||||
write(pid_fd, pid_buf, n);
|
||||
if (write(pid_fd, pid_buf, n) < 0) {
|
||||
perror("PID file write");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
close(pid_fd);
|
||||
}
|
||||
|
||||
|
@ -365,8 +368,10 @@ int main(int argc, char **argv)
|
|||
else
|
||||
__setlogmask(LOG_UPTO(LOG_INFO));
|
||||
|
||||
if (isatty(fileno(stdout)) && !c.foreground)
|
||||
daemon(0, 0);
|
||||
if (isatty(fileno(stdout)) && !c.foreground && daemon(0, 0)) {
|
||||
perror("daemon");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
pid_file(&c);
|
||||
|
||||
|
|
15
pasta.c
15
pasta.c
|
@ -184,7 +184,8 @@ void pasta_start_ns(struct ctx *c)
|
|||
|
||||
snprintf(proc_path, PATH_MAX, "/proc/%i/ns/net",
|
||||
pasta_child_pid);
|
||||
readlink(proc_path, pasta_child_ns, PATH_MAX);
|
||||
if (readlink(proc_path, pasta_child_ns, PATH_MAX) < 0)
|
||||
warn("Cannot read link to ns, won't clean up on exit");
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -198,20 +199,24 @@ void pasta_start_ns(struct ctx *c)
|
|||
snprintf(buf, BUFSIZ, "%u %u %u", 0, euid, 1);
|
||||
|
||||
fd = open("/proc/self/uid_map", O_WRONLY);
|
||||
write(fd, buf, strlen(buf));
|
||||
if (write(fd, buf, strlen(buf)) < 0)
|
||||
warn("Cannot set uid_map in namespace");
|
||||
close(fd);
|
||||
|
||||
fd = open("/proc/self/setgroups", O_WRONLY);
|
||||
write(fd, "deny", sizeof("deny"));
|
||||
if (write(fd, "deny", sizeof("deny")))
|
||||
warn("Cannot write to setgroups in namespace");
|
||||
close(fd);
|
||||
|
||||
fd = open("/proc/self/gid_map", O_WRONLY);
|
||||
write(fd, buf, strlen(buf));
|
||||
if (write(fd, buf, strlen(buf)) < 0)
|
||||
warn("Cannot set gid_map in namespace");
|
||||
close(fd);
|
||||
}
|
||||
|
||||
fd = open("/proc/sys/net/ipv4/ping_group_range", O_WRONLY);
|
||||
write(fd, "0 0", strlen("0 0"));
|
||||
if (write(fd, "0 0", strlen("0 0")) < 0)
|
||||
warn("Cannot set ping_group_range, ICMP requests might fail");
|
||||
close(fd);
|
||||
|
||||
shell = getenv("SHELL") ? getenv("SHELL") : "/bin/sh";
|
||||
|
|
35
pcap.c
35
pcap.c
|
@ -23,6 +23,7 @@
|
|||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
|
@ -87,8 +88,8 @@ void pcap(char *pkt, size_t len)
|
|||
h.tv_usec = tv.tv_usec;
|
||||
h.caplen = h.len = len;
|
||||
|
||||
write(pcap_fd, &h, sizeof(h));
|
||||
write(pcap_fd, pkt, len);
|
||||
if (write(pcap_fd, &h, sizeof(h)) < 0 || write(pcap_fd, pkt, len) < 0)
|
||||
debug("Cannot log packet, length %u", len);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -98,6 +99,7 @@ void pcap(char *pkt, size_t len)
|
|||
void pcapm(struct msghdr *mh)
|
||||
{
|
||||
struct pcap_pkthdr h;
|
||||
struct iovec *iov;
|
||||
struct timeval tv;
|
||||
unsigned int i;
|
||||
|
||||
|
@ -109,13 +111,19 @@ void pcapm(struct msghdr *mh)
|
|||
h.tv_usec = tv.tv_usec;
|
||||
|
||||
for (i = 0; i < mh->msg_iovlen; i++) {
|
||||
struct iovec *iov = &mh->msg_iov[i];
|
||||
iov = &mh->msg_iov[i];
|
||||
|
||||
h.caplen = h.len = iov->iov_len - 4;
|
||||
write(pcap_fd, &h, sizeof(h));
|
||||
|
||||
write(pcap_fd, (char *)iov->iov_base + 4, iov->iov_len - 4);
|
||||
if (write(pcap_fd, &h, sizeof(h)) < 0)
|
||||
goto fail;
|
||||
if (write(pcap_fd, (char *)iov->iov_base + 4, iov->iov_len - 4))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return;
|
||||
fail:
|
||||
debug("Cannot log packet, length %u", iov->iov_len - 4);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -125,6 +133,7 @@ void pcapm(struct msghdr *mh)
|
|||
void pcapmm(struct mmsghdr *mmh, unsigned int vlen)
|
||||
{
|
||||
struct pcap_pkthdr h;
|
||||
struct iovec *iov;
|
||||
struct timeval tv;
|
||||
unsigned int i, j;
|
||||
|
||||
|
@ -139,15 +148,20 @@ void pcapmm(struct mmsghdr *mmh, unsigned int vlen)
|
|||
struct msghdr *mh = &mmh[i].msg_hdr;
|
||||
|
||||
for (j = 0; j < mh->msg_iovlen; j++) {
|
||||
struct iovec *iov = &mh->msg_iov[j];
|
||||
iov = &mh->msg_iov[j];
|
||||
|
||||
h.caplen = h.len = iov->iov_len - 4;
|
||||
write(pcap_fd, &h, sizeof(h));
|
||||
|
||||
write(pcap_fd, (char *)iov->iov_base + 4,
|
||||
iov->iov_len - 4);
|
||||
if (write(pcap_fd, &h, sizeof(h)) < 0)
|
||||
goto fail;
|
||||
if (write(pcap_fd, (char *)iov->iov_base + 4,
|
||||
iov->iov_len - 4) < 0)
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
return;
|
||||
fail:
|
||||
debug("Cannot log packet, length %u", iov->iov_len - 4);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -194,5 +208,6 @@ void pcap_init(struct ctx *c, int index)
|
|||
|
||||
info("Saving packet capture at %s", c->pcap);
|
||||
|
||||
write(pcap_fd, &pcap_hdr, sizeof(pcap_hdr));
|
||||
if (write(pcap_fd, &pcap_hdr, sizeof(pcap_hdr)) < 0)
|
||||
warn("Cannot write PCAP header: %s", strerror(errno));
|
||||
}
|
||||
|
|
|
@ -146,6 +146,9 @@ uint32_t siphash_12b(const uint8_t *in, const uint64_t *k)
|
|||
*
|
||||
* Return: the 64-bit hash output
|
||||
*/
|
||||
#if SIPHASH_20B_NOINLINE
|
||||
__attribute__((__noinline__)) /* See comment in Makefile */
|
||||
#endif
|
||||
uint64_t siphash_20b(const uint8_t *in, const uint64_t *k)
|
||||
{
|
||||
uint32_t *in32 = (uint32_t *)in;
|
||||
|
|
36
tcp.c
36
tcp.c
|
@ -311,6 +311,7 @@
|
|||
#include <sched.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <net/ethernet.h>
|
||||
|
@ -1103,6 +1104,9 @@ static int tcp_hash_match(struct tcp_tap_conn *conn, int af, void *addr,
|
|||
*
|
||||
* Return: hash value, already modulo size of the hash table
|
||||
*/
|
||||
#if TCP_HASH_NOINLINE
|
||||
__attribute__((__noinline__)) /* See comment in Makefile */
|
||||
#endif
|
||||
static unsigned int tcp_hash(struct ctx *c, int af, void *addr,
|
||||
in_port_t tap_port, in_port_t sock_port)
|
||||
{
|
||||
|
@ -1322,8 +1326,9 @@ static void tcp_l2_flags_buf_flush(struct ctx *c)
|
|||
for (i = 0; i < mh.msg_iovlen; i++) {
|
||||
struct iovec *iov = &mh.msg_iov[i];
|
||||
|
||||
write(c->fd_tap, (char *)iov->iov_base + 4,
|
||||
iov->iov_len - 4);
|
||||
if (write(c->fd_tap, (char *)iov->iov_base + 4,
|
||||
iov->iov_len - 4) < 0)
|
||||
debug("tap write: %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
tcp6_l2_flags_buf_used = 0;
|
||||
|
@ -1338,8 +1343,9 @@ static void tcp_l2_flags_buf_flush(struct ctx *c)
|
|||
for (i = 0; i < mh.msg_iovlen; i++) {
|
||||
struct iovec *iov = &mh.msg_iov[i];
|
||||
|
||||
write(c->fd_tap, (char *)iov->iov_base + 4,
|
||||
iov->iov_len - 4);
|
||||
if (write(c->fd_tap, (char *)iov->iov_base + 4,
|
||||
iov->iov_len - 4) < 0)
|
||||
debug("tap write: %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
tcp4_l2_flags_buf_used = 0;
|
||||
|
@ -1392,8 +1398,9 @@ static void tcp_l2_buf_flush(struct ctx *c)
|
|||
for (i = 0; i < mh.msg_iovlen; i++) {
|
||||
struct iovec *iov = &mh.msg_iov[i];
|
||||
|
||||
write(c->fd_tap, (char *)iov->iov_base + 4,
|
||||
iov->iov_len - 4);
|
||||
if (write(c->fd_tap, (char *)iov->iov_base + 4,
|
||||
iov->iov_len - 4) < 0)
|
||||
debug("tap write: %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
tcp6_l2_buf_used = tcp6_l2_buf_bytes = 0;
|
||||
|
@ -1413,8 +1420,9 @@ v4:
|
|||
for (i = 0; i < mh.msg_iovlen; i++) {
|
||||
struct iovec *iov = &mh.msg_iov[i];
|
||||
|
||||
write(c->fd_tap, (char *)iov->iov_base + 4,
|
||||
iov->iov_len - 4);
|
||||
if (write(c->fd_tap, (char *)iov->iov_base + 4,
|
||||
iov->iov_len - 4) < 0)
|
||||
debug("tap write: %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
tcp4_l2_buf_used = tcp4_l2_buf_bytes = 0;
|
||||
|
@ -1628,14 +1636,16 @@ static int tcp_send_to_tap(struct ctx *c, struct tcp_tap_conn *conn, int flags,
|
|||
iov = tcp4_l2_flags_iov_tap + tcp4_l2_flags_buf_used;
|
||||
p = b4 = tcp4_l2_flags_buf + tcp4_l2_flags_buf_used++;
|
||||
th = &b4->th;
|
||||
|
||||
/* gcc 11.2 would complain on data = (char *)(th + 1); */
|
||||
data = b4->opts;
|
||||
} else {
|
||||
iov = tcp6_l2_flags_iov_tap + tcp6_l2_flags_buf_used;
|
||||
p = b6 = tcp6_l2_flags_buf + tcp6_l2_flags_buf_used++;
|
||||
th = &b6->th;
|
||||
data = b6->opts;
|
||||
}
|
||||
|
||||
data = (char *)(th + 1);
|
||||
|
||||
if (flags & SYN) {
|
||||
uint16_t mss;
|
||||
|
||||
|
@ -3538,7 +3548,11 @@ int tcp_sock_init(struct ctx *c, struct timespec *now)
|
|||
in_port_t port;
|
||||
int i;
|
||||
|
||||
getrandom(&c->tcp.hash_secret, sizeof(c->tcp.hash_secret), GRND_RANDOM);
|
||||
if (getrandom(&c->tcp.hash_secret, sizeof(c->tcp.hash_secret),
|
||||
GRND_RANDOM) < 0) {
|
||||
perror("TCP initial sequence getrandom");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
for (port = 0; port < USHRT_MAX; port++) {
|
||||
if (!bitmap_isset(c->tcp.port_to_tap, port))
|
||||
|
|
8
udp.c
8
udp.c
|
@ -536,8 +536,8 @@ static void udp_sock_handler_splice(struct ctx *c, union epoll_ref ref,
|
|||
uint32_t events, struct timespec *now)
|
||||
{
|
||||
struct msghdr *mh = &udp_splice_mmh_recv[0].msg_hdr;
|
||||
in_port_t src, dst = ref.udp.port, send_dst = 0;
|
||||
struct sockaddr_storage *sa_s = mh->msg_name;
|
||||
in_port_t src, dst = ref.udp.port, send_dst;
|
||||
int s, v6 = ref.udp.v6, n, i;
|
||||
|
||||
if (!(events & EPOLLIN))
|
||||
|
@ -721,7 +721,8 @@ void udp_sock_handler(struct ctx *c, union epoll_ref ref, uint32_t events,
|
|||
|
||||
if (c->mode == MODE_PASTA) {
|
||||
ip_len += sizeof(struct ethhdr);
|
||||
write(c->fd_tap, &b->eh, ip_len);
|
||||
if (write(c->fd_tap, &b->eh, ip_len) < 0)
|
||||
debug("tap write: %s", strerror(errno));
|
||||
pcap((char *)&b->eh, ip_len);
|
||||
continue;
|
||||
}
|
||||
|
@ -791,7 +792,8 @@ void udp_sock_handler(struct ctx *c, union epoll_ref ref, uint32_t events,
|
|||
|
||||
if (c->mode == MODE_PASTA) {
|
||||
ip_len += sizeof(struct ethhdr);
|
||||
write(c->fd_tap, &b->eh, ip_len);
|
||||
if (write(c->fd_tap, &b->eh, ip_len) < 0)
|
||||
debug("tap write: %s", strerror(errno));
|
||||
pcap((char *)&b->eh, ip_len);
|
||||
continue;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue