]> granicus.if.org Git - strace/commitdiff
tests: extend netlink protocol check
authorDmitry V. Levin <ldv@altlinux.org>
Thu, 7 Jul 2016 09:49:26 +0000 (09:49 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Thu, 7 Jul 2016 10:01:25 +0000 (10:01 +0000)
* tests/netlink_protocol.c (send_query): Check that no part
of netlink message is fetched beyond the end of message.
Check decoding of zero address and zero length messages.
Check decoding of messages with nlmsg_len exceeding message length.

tests/netlink_protocol.c

index eb6a843d92a16431cafca0647214c947a2d8ecc2..8afea597f1e89f9eb11d39ef87161c301fb21d90 100644 (file)
  */
 
 #include "tests.h"
+#include <stdio.h>
 #include <string.h>
 #include <unistd.h>
 #include <netinet/in.h>
-#include <stdio.h>
 #include <linux/netlink.h>
 #include <linux/sock_diag.h>
 #include <linux/netlink_diag.h>
 static void
 send_query(const int fd)
 {
-       struct {
+       static const struct req {
                struct nlmsghdr nlh;
-               char magic[4];
-       } req = {
+               const char magic[4];
+       } c_req = {
                .nlh = {
-                       .nlmsg_len = sizeof(req),
+                       .nlmsg_len = sizeof(struct req),
                        .nlmsg_type = NLMSG_NOOP,
                        .nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST
                },
                .magic = "abcd"
        };
+       struct req *const req = tail_memdup(&c_req, sizeof(c_req));
+
+       /* zero address */
+       if (sendto(fd, NULL, sizeof(*req), MSG_DONTWAIT, NULL, 0) != -1)
+               perror_msg_and_skip("sendto");
+
+       printf("sendto(%d, NULL, %u, MSG_DONTWAIT, NULL, 0) = -1 %s (%m)\n",
+              fd, (unsigned) sizeof(*req), errno2name());
+
+       /* zero length */
+       if (sendto(fd, req, 0, MSG_DONTWAIT, NULL, 0) != 0)
+               perror_msg_and_skip("sendto");
+
+       printf("sendto(%d, \"\", 0, MSG_DONTWAIT, NULL, 0) = 0\n", fd);
+
+       /* zero address and length */
+       if (sendto(fd, NULL, 0, MSG_DONTWAIT, NULL, 0) != 0)
+               perror_msg_and_skip("sendto");
+
+       printf("sendto(%d, NULL, 0, MSG_DONTWAIT, NULL, 0) = 0\n", fd);
 
+       /* unfetchable struct nlmsghdr */
        const void *const efault = tail_alloc(sizeof(struct nlmsghdr) - 1);
+       sendto(fd, efault, sizeof(struct nlmsghdr), MSG_DONTWAIT, NULL, 0);
 
-       if (sendto(fd, &req, sizeof(req), MSG_DONTWAIT, NULL, 0) !=
-           (unsigned) sizeof(req))
+       printf("sendto(%d, %p, %u, MSG_DONTWAIT, NULL, 0) = -1 EFAULT (%m)\n",
+              fd, efault, (unsigned) sizeof(struct nlmsghdr));
+
+       /* whole message length < sizeof(struct nlmsghdr) */
+       if (sendto(fd, req->magic, sizeof(req->magic), MSG_DONTWAIT, NULL, 0)
+           != (unsigned) sizeof(req->magic))
+               perror_msg_and_skip("sendto");
+
+       printf("sendto(%d, \"abcd\", %u, MSG_DONTWAIT, NULL, 0) = %u\n",
+              fd, (unsigned) sizeof(req->magic), (unsigned) sizeof(req->magic));
+
+       /* a single message with some data */
+       if (sendto(fd, req, sizeof(*req), MSG_DONTWAIT, NULL, 0) !=
+           (unsigned) sizeof(*req))
                perror_msg_and_skip("sendto");
 
        printf("sendto(%d, {{len=%u, type=NLMSG_NOOP, flags=NLM_F_REQUEST|0x%x"
               ", seq=0, pid=0}, \"abcd\"}, %u, MSG_DONTWAIT, NULL, 0) = %u\n",
-              fd, (unsigned) sizeof(req), NLM_F_DUMP,
-              (unsigned) sizeof(req), (unsigned) sizeof(req));
+              fd, req->nlh.nlmsg_len, NLM_F_DUMP,
+              (unsigned) sizeof(*req), (unsigned) sizeof(*req));
 
-       /* data length is equal to sizeof(struct nlmsghdr) */
-       req.nlh.nlmsg_len = sizeof(req.nlh);
+       /* a single message without data */
+       req->nlh.nlmsg_len = sizeof(req->nlh);
 
-       if (sendto(fd, &req.nlh, sizeof(req.nlh), MSG_DONTWAIT, NULL, 0) !=
-           (unsigned) sizeof(req.nlh))
+       if (sendto(fd, &req->nlh, sizeof(req->nlh), MSG_DONTWAIT, NULL, 0)
+           != (unsigned) sizeof(req->nlh))
                perror_msg_and_skip("sendto");
 
        printf("sendto(%d, {{len=%u, type=NLMSG_NOOP, flags=NLM_F_REQUEST|0x%x"
               ", seq=0, pid=0}}, %u, MSG_DONTWAIT, NULL, 0) = %u\n",
-              fd, (unsigned) sizeof(req.nlh), NLM_F_DUMP,
-              (unsigned) sizeof(req.nlh), (unsigned) sizeof(req.nlh));
+              fd, req->nlh.nlmsg_len, NLM_F_DUMP,
+              (unsigned) sizeof(req->nlh), (unsigned) sizeof(req->nlh));
 
-       /* data length is less than sizeof(struct nlmsghdr) */
-       if (sendto(fd, &req.magic, sizeof(req.magic), MSG_DONTWAIT, NULL, 0) !=
-           (unsigned) sizeof(req.magic))
+       /* nlmsg_len > whole message length */
+       req->nlh.nlmsg_len = sizeof(*req) + 8;
+       if (sendto(fd, req, sizeof(*req), MSG_DONTWAIT, NULL, 0) !=
+           (unsigned) sizeof(*req))
                perror_msg_and_skip("sendto");
 
-       printf("sendto(%d, \"abcd\", %u, MSG_DONTWAIT, NULL, 0) = %u\n",
-              fd, (unsigned) sizeof(req.magic), (unsigned) sizeof(req.magic));
-
-       sendto(fd, efault, sizeof(struct nlmsghdr), MSG_DONTWAIT, NULL, 0);
-
-       printf("sendto(%d, %p, %u, MSG_DONTWAIT, NULL, 0) = -1 "
-              "EFAULT (%m)\n", fd, efault, (unsigned) sizeof(struct nlmsghdr));
+       printf("sendto(%d, {{len=%u, type=NLMSG_NOOP, flags=NLM_F_REQUEST|0x%x"
+              ", seq=0, pid=0}, \"abcd\"}, %u, MSG_DONTWAIT, NULL, 0) = %u\n",
+              fd, req->nlh.nlmsg_len, NLM_F_DUMP,
+              (unsigned) sizeof(*req), (unsigned) sizeof(*req));
 }
 
 int main(void)