]> granicus.if.org Git - strace/commitdiff
Workaround signedness bugs in system NLMSG_OK reported by -Wsign-compare
authorDmitry V. Levin <ldv@altlinux.org>
Sun, 16 Sep 2018 21:32:37 +0000 (21:32 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Sun, 16 Sep 2018 21:32:37 +0000 (21:32 +0000)
Introduce a replacement for NLMSG_OK provided by <linux/netlink.h> since
that system macro contains signedness bugs that are not going to be fixed.

* netlink.h: Include <stdbool.h>.
(is_nlmsg_ok): New static inline function.
* socketutils.c (receive_responses): Use it instead of NLMSG_OK.
* tests/netlink_inet_diag.c (check_responses): Likewise.
* tests/netlink_netlink_diag.c (check_responses): Likewise.
* tests/netlink_unix_diag.c (check_responses): Likewise.

Closes: https://github.com/strace/strace/issues/79
netlink.h
socketutils.c
tests/netlink_inet_diag.c
tests/netlink_netlink_diag.c
tests/netlink_unix_diag.c

index 42e7802e73253bad4e11e75f095a9afc0aaca717..48abe0b861e192a44967e5e4a1b9fc1142abf178 100644 (file)
--- a/netlink.h
+++ b/netlink.h
@@ -29,6 +29,7 @@
 #ifndef STRACE_NETLINK_H
 #define STRACE_NETLINK_H
 
+#include <stdbool.h>
 #include <sys/socket.h>
 #include <linux/netlink.h>
 
 # define NLA_TYPE_MASK         ~(NLA_F_NESTED | NLA_F_NET_BYTEORDER)
 #endif
 
+static inline bool
+is_nlmsg_ok(const struct nlmsghdr *const nlh, const ssize_t len)
+{
+       return len >= (ssize_t) sizeof(*nlh)
+              && nlh->nlmsg_len >= sizeof(*nlh)
+              && (size_t) len >= nlh->nlmsg_len;
+}
+
 #endif /* !STRACE_NETLINK_H */
index aa0752c377f76c323c3e8a676b8684e2a3c4e3d2..c3f28a1bf71b01406636fc86b62abebc9fad4f00 100644 (file)
@@ -237,9 +237,9 @@ receive_responses(struct tcb *tcp, const int fd, const unsigned long inode,
                }
 
                const struct nlmsghdr *h = &hdr_buf.hdr;
-               if (!NLMSG_OK(h, ret))
+               if (!is_nlmsg_ok(h, ret))
                        return false;
-               for (; NLMSG_OK(h, ret); h = NLMSG_NEXT(h, ret)) {
+               for (; is_nlmsg_ok(h, ret); h = NLMSG_NEXT(h, ret)) {
                        if (h->nlmsg_type != expected_msg_type)
                                return false;
                        const int rc = parser(NLMSG_DATA(h),
index 8b3d8af0a4737059013a84d6906ad9db0d13a333..dc990aeb3f29754330c1568ad5586e43190c5bc2 100644 (file)
@@ -100,8 +100,8 @@ check_responses(const int fd)
                perror_msg_and_skip("recvmsg");
 
        struct nlmsghdr *h = &hdr_buf.hdr;
-       if (!NLMSG_OK(h, ret))
-               error_msg_and_skip("!NLMSG_OK");
+       if (!is_nlmsg_ok(h, ret))
+               error_msg_and_skip("!is_nlmsg_ok");
        if (h->nlmsg_type == NLMSG_ERROR) {
                const struct nlmsgerr *err = NLMSG_DATA(h);
                if (h->nlmsg_len < NLMSG_LENGTH(sizeof(*err)))
index a682f7c6977cb4a9fbe4250e506195de16f2bf81..ee651eefb8d24848948322facd2d04d779dbc315 100644 (file)
@@ -100,8 +100,8 @@ check_responses(const int fd)
                perror_msg_and_skip("recvmsg");
 
        struct nlmsghdr *h = &hdr_buf.hdr;
-       if (!NLMSG_OK(h, ret))
-               error_msg_and_skip("!NLMSG_OK");
+       if (!is_nlmsg_ok(h, ret))
+               error_msg_and_skip("!is_nlmsg_ok");
        if (h->nlmsg_type == NLMSG_ERROR) {
                const struct nlmsgerr *err = NLMSG_DATA(h);
                if (h->nlmsg_len < NLMSG_LENGTH(sizeof(*err)))
index e15092381dd839809051a67809fb5a67bd5b913a..f74e7306d9ff799fc3f6d3b5f80d70f9d307ec88 100644 (file)
@@ -104,8 +104,8 @@ check_responses(const int fd)
                perror_msg_and_skip("recvmsg");
 
        struct nlmsghdr *h = &hdr_buf.hdr;
-       if (!NLMSG_OK(h, ret))
-               error_msg_and_skip("!NLMSG_OK");
+       if (!is_nlmsg_ok(h, ret))
+               error_msg_and_skip("!is_nlmsg_ok");
        if (h->nlmsg_type == NLMSG_ERROR) {
                const struct nlmsgerr *err = NLMSG_DATA(h);
                if (h->nlmsg_len < NLMSG_LENGTH(sizeof(*err)))