These are reported by clang-tidy and Coverity after David's series, I'm applying minimal fixes for them to go ahead and apply those series, as we should really make a new release at this point. They are all trivial, I'm posting them to ease reviews but I already applied these. Stefano Brivio (3): netlink: Sequence numbers are actually 32 bits wide port_fwd: Don't try to read bound ports from invalid file handles log: Match implicit va_start() with va_end() in vlogmsg() log.c | 2 ++ netlink.c | 20 ++++++++++---------- port_fwd.c | 3 +++ 3 files changed, 15 insertions(+), 10 deletions(-) -- 2.39.2
Harmless, as we use sequence numbers monotonically anyway, but now clang-tidy reports: /home/sbrivio/passt/netlink.c:155:7: error: format specifies type 'unsigned short' but the argument has type '__u32' (aka 'unsigned int') [clang-diagnostic-format,-warnings-as-errors] nh->nlmsg_seq, seq); ^ /home/sbrivio/passt/log.h:26:7: note: expanded from macro 'die' err(__VA_ARGS__); \ ^~~~~~~~~~~ /home/sbrivio/passt/log.h:19:34: note: expanded from macro 'err' ^~~~~~~~~~~ Suppressed 222820 warnings (222816 in non-user code, 4 NOLINT). Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well. 1 warning treated as error make: *** [Makefile:255: clang-tidy] Error 1 Fixes: 9d4ab98d538f ("netlink: Add nl_do() helper for simple operations with error checking") Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- netlink.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/netlink.c b/netlink.c index 768c6fd..6cc04a0 100644 --- a/netlink.c +++ b/netlink.c @@ -113,7 +113,7 @@ fail: * * Return: sequence number of request on success, terminates on error */ -static uint16_t nl_send(int s, void *req, uint16_t type, +static uint32_t nl_send(int s, void *req, uint16_t type, uint16_t flags, ssize_t len) { struct nlmsghdr *nh; @@ -146,12 +146,12 @@ static uint16_t nl_send(int s, void *req, uint16_t type, * > 0 @n if there are more responses to request @seq * terminates if sequence numbers are out of sync */ -static int nl_status(const struct nlmsghdr *nh, ssize_t n, uint16_t seq) +static int nl_status(const struct nlmsghdr *nh, ssize_t n, uint32_t seq) { ASSERT(NLMSG_OK(nh, n)); if (nh->nlmsg_seq != seq) - die("netlink: Unexpected sequence number (%hu != %hu)", + die("netlink: Unexpected sequence number (%u != %u)", nh->nlmsg_seq, seq); if (nh->nlmsg_type == NLMSG_DONE) { @@ -229,7 +229,7 @@ static int nl_do(int s, void *req, uint16_t type, uint16_t flags, ssize_t len) struct nlmsghdr *nh; char buf[NLBUFSIZ]; ssize_t status; - uint16_t seq; + uint32_t seq; seq = nl_send(s, req, type, flags, len); nl_foreach(nh, status, s, buf, seq) @@ -259,7 +259,7 @@ unsigned int nl_get_ext_if(int s, sa_family_t af) struct rtattr *rta; char buf[NLBUFSIZ]; ssize_t status; - uint16_t seq; + uint32_t seq; size_t na; seq = nl_send(s, &req, RTM_GETROUTE, NLM_F_DUMP, sizeof(req)); @@ -313,7 +313,7 @@ int nl_route_get_def(int s, unsigned int ifi, sa_family_t af, void *gw) bool found = false; char buf[NLBUFSIZ]; ssize_t status; - uint16_t seq; + uint32_t seq; seq = nl_send(s, &req, RTM_GETROUTE, NLM_F_DUMP, sizeof(req)); nl_foreach_oftype(nh, status, s, buf, seq, RTM_NEWROUTE) { @@ -438,7 +438,7 @@ int nl_route_dup(int s_src, unsigned int ifi_src, unsigned dup_routes = 0; struct nlmsghdr *nh; char buf[NLBUFSIZ]; - uint16_t seq; + uint32_t seq; unsigned i; seq = nl_send(s_src, &req, RTM_GETROUTE, NLM_F_DUMP, sizeof(req)); @@ -550,7 +550,7 @@ int nl_addr_get(int s, unsigned int ifi, sa_family_t af, struct nlmsghdr *nh; char buf[NLBUFSIZ]; ssize_t status; - uint16_t seq; + uint32_t seq; seq = nl_send(s, &req, RTM_GETADDR, NLM_F_DUMP, sizeof(req)); nl_foreach_oftype(nh, status, s, buf, seq, RTM_NEWADDR) { @@ -674,7 +674,7 @@ int nl_addr_dup(int s_src, unsigned int ifi_src, char buf[NLBUFSIZ]; struct nlmsghdr *nh; ssize_t status; - uint16_t seq; + uint32_t seq; int rc = 0; seq = nl_send(s_src, &req, RTM_GETADDR, NLM_F_DUMP, sizeof(req)); @@ -729,7 +729,7 @@ int nl_link_get_mac(int s, unsigned int ifi, void *mac) struct nlmsghdr *nh; char buf[NLBUFSIZ]; ssize_t status; - uint16_t seq; + uint32_t seq; seq = nl_send(s, &req, RTM_GETLINK, 0, sizeof(req)); nl_foreach_oftype(nh, status, s, buf, seq, RTM_NEWLINK) { -- 2.39.2
On Tue, Nov 07, 2023 at 01:28:31PM +0100, Stefano Brivio wrote:Harmless, as we use sequence numbers monotonically anyway, but now clang-tidy reports: /home/sbrivio/passt/netlink.c:155:7: error: format specifies type 'unsigned short' but the argument has type '__u32' (aka 'unsigned int') [clang-diagnostic-format,-warnings-as-errors] nh->nlmsg_seq, seq); ^ /home/sbrivio/passt/log.h:26:7: note: expanded from macro 'die' err(__VA_ARGS__); \ ^~~~~~~~~~~ /home/sbrivio/passt/log.h:19:34: note: expanded from macro 'err' ^~~~~~~~~~~ Suppressed 222820 warnings (222816 in non-user code, 4 NOLINT). Use -header-filter=.* to display errors from all non-system headers. Use -system-headers to display errors from system headers as well. 1 warning treated as error make: *** [Makefile:255: clang-tidy] Error 1Hrm. I wonder why clang-tidy didn't find this one for me :/Fixes: 9d4ab98d538f ("netlink: Add nl_do() helper for simple operations with error checking") Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- netlink.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/netlink.c b/netlink.c index 768c6fd..6cc04a0 100644 --- a/netlink.c +++ b/netlink.c @@ -113,7 +113,7 @@ fail: * * Return: sequence number of request on success, terminates on error */ -static uint16_t nl_send(int s, void *req, uint16_t type, +static uint32_t nl_send(int s, void *req, uint16_t type, uint16_t flags, ssize_t len) { struct nlmsghdr *nh; @@ -146,12 +146,12 @@ static uint16_t nl_send(int s, void *req, uint16_t type, * > 0 @n if there are more responses to request @seq * terminates if sequence numbers are out of sync */ -static int nl_status(const struct nlmsghdr *nh, ssize_t n, uint16_t seq) +static int nl_status(const struct nlmsghdr *nh, ssize_t n, uint32_t seq) { ASSERT(NLMSG_OK(nh, n)); if (nh->nlmsg_seq != seq) - die("netlink: Unexpected sequence number (%hu != %hu)", + die("netlink: Unexpected sequence number (%u != %u)", nh->nlmsg_seq, seq); if (nh->nlmsg_type == NLMSG_DONE) { @@ -229,7 +229,7 @@ static int nl_do(int s, void *req, uint16_t type, uint16_t flags, ssize_t len) struct nlmsghdr *nh; char buf[NLBUFSIZ]; ssize_t status; - uint16_t seq; + uint32_t seq; seq = nl_send(s, req, type, flags, len); nl_foreach(nh, status, s, buf, seq) @@ -259,7 +259,7 @@ unsigned int nl_get_ext_if(int s, sa_family_t af) struct rtattr *rta; char buf[NLBUFSIZ]; ssize_t status; - uint16_t seq; + uint32_t seq; size_t na; seq = nl_send(s, &req, RTM_GETROUTE, NLM_F_DUMP, sizeof(req)); @@ -313,7 +313,7 @@ int nl_route_get_def(int s, unsigned int ifi, sa_family_t af, void *gw) bool found = false; char buf[NLBUFSIZ]; ssize_t status; - uint16_t seq; + uint32_t seq; seq = nl_send(s, &req, RTM_GETROUTE, NLM_F_DUMP, sizeof(req)); nl_foreach_oftype(nh, status, s, buf, seq, RTM_NEWROUTE) { @@ -438,7 +438,7 @@ int nl_route_dup(int s_src, unsigned int ifi_src, unsigned dup_routes = 0; struct nlmsghdr *nh; char buf[NLBUFSIZ]; - uint16_t seq; + uint32_t seq; unsigned i; seq = nl_send(s_src, &req, RTM_GETROUTE, NLM_F_DUMP, sizeof(req)); @@ -550,7 +550,7 @@ int nl_addr_get(int s, unsigned int ifi, sa_family_t af, struct nlmsghdr *nh; char buf[NLBUFSIZ]; ssize_t status; - uint16_t seq; + uint32_t seq; seq = nl_send(s, &req, RTM_GETADDR, NLM_F_DUMP, sizeof(req)); nl_foreach_oftype(nh, status, s, buf, seq, RTM_NEWADDR) { @@ -674,7 +674,7 @@ int nl_addr_dup(int s_src, unsigned int ifi_src, char buf[NLBUFSIZ]; struct nlmsghdr *nh; ssize_t status; - uint16_t seq; + uint32_t seq; int rc = 0; seq = nl_send(s_src, &req, RTM_GETADDR, NLM_F_DUMP, sizeof(req)); @@ -729,7 +729,7 @@ int nl_link_get_mac(int s, unsigned int ifi, void *mac) struct nlmsghdr *nh; char buf[NLBUFSIZ]; ssize_t status; - uint16_t seq; + uint32_t seq; seq = nl_send(s, &req, RTM_GETLINK, 0, sizeof(req)); nl_foreach_oftype(nh, status, s, buf, seq, RTM_NEWLINK) {-- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
This is a minimal fix for what would be reported by Coverity as "Improper use of negative value" (CWE-394): port_fwd_init() doesn't guarantee that all the pre-opened file handles are actually valid. We should probably warn on failing open() and open_in_ns() in port_fwd_init(), too, but that's outside the scope of this minimal fix. Before commit 5a0485425bc9 ("port_fwd: Pre-open /proc/net/* files rather than on-demand"), we used to have a single open() call and a check after it. Fixes: 5a0485425bc9 ("port_fwd: Pre-open /proc/net/* files rather than on-demand") Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- port_fwd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/port_fwd.c b/port_fwd.c index fc4d5cb..eac8d2f 100644 --- a/port_fwd.c +++ b/port_fwd.c @@ -45,6 +45,9 @@ static void procfs_scan_listen(int fd, unsigned int lstate, unsigned int state; char *line; + if (fd < 0) + return; + if (lseek(fd, 0, SEEK_SET)) { warn("lseek() failed on /proc/net file: %s", strerror(errno)); return; -- 2.39.2
According to C99, 7.15.1: Each invocation of the va_start and va_copy macros shall be matched by a corresponding invocation of the va_end macro in the same function and the same applies to C11. I still have to come across a platform where va_end() actually does something, but thus spake the standard. This would be reported by Coverity as "Missing varargs init or cleanup" (CWE-573). Fixes: c0426ff10bc9 ("log: Add vlogmsg()") Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- log.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/log.c b/log.c index 95c4fa4..b206f72 100644 --- a/log.c +++ b/log.c @@ -67,6 +67,8 @@ void vlogmsg(int pri, const char *format, va_list ap) logfile_write(pri, format, ap2); else if (!(setlogmask(0) & LOG_MASK(LOG_DEBUG))) passt_vsyslog(pri, format, ap2); + + va_end(ap2); } if ((setlogmask(0) & LOG_MASK(LOG_DEBUG) && log_file == -1) || -- 2.39.2
On Tue, Nov 07, 2023 at 01:28:33PM +0100, Stefano Brivio wrote:According to C99, 7.15.1: Each invocation of the va_start and va_copy macros shall be matched by a corresponding invocation of the va_end macro in the same function and the same applies to C11. I still have to come across a platform where va_end() actually does something, but thus spake the standard. This would be reported by Coverity as "Missing varargs init or cleanup" (CWE-573).Oops. I'm pretty sure this one will cause real problems on some platforms. Well caught.Fixes: c0426ff10bc9 ("log: Add vlogmsg()") Signed-off-by: Stefano Brivio <sbrivio(a)redhat.com> --- log.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/log.c b/log.c index 95c4fa4..b206f72 100644 --- a/log.c +++ b/log.c @@ -67,6 +67,8 @@ void vlogmsg(int pri, const char *format, va_list ap) logfile_write(pri, format, ap2); else if (!(setlogmask(0) & LOG_MASK(LOG_DEBUG))) passt_vsyslog(pri, format, ap2); + + va_end(ap2); } if ((setlogmask(0) & LOG_MASK(LOG_DEBUG) && log_file == -1) ||-- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson