netlink: make the check for "send from tx_ring" deterministic
authorAl Viro <viro@zeniv.linux.org.uk>
Sat, 13 Dec 2014 04:02:36 +0000 (23:02 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Wed, 4 Feb 2015 06:34:13 +0000 (01:34 -0500)
As it is, zero msg_iovlen means that the first iovec in the kernel
array of iovecs is left uninitialized, so checking if its ->iov_base
is NULL is random.  Since the real users of that thing are doing
sendto(fd, NULL, 0, ...), they are getting msg_iovlen = 1 and
msg_iov[0] = {NULL, 0}, which is what this test is trying to catch.
As suggested by davem, let's just check that msg_iovlen was 1 and
msg_iov[0].iov_base was NULL - _that_ is well-defined and it catches
what we want to catch.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
net/netlink/af_netlink.c

index a36777b7cfb6d89967d25fe784a3224caaccedab..4fd38a612ff6e750cfce70a1a16d6aa794a84c42 100644 (file)
@@ -2298,7 +2298,12 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
                        goto out;
        }
 
+       /* It's a really convoluted way for userland to ask for mmaped
+        * sendmsg(), but that's what we've got...
+        */
        if (netlink_tx_is_mmaped(sk) &&
+           msg->msg_iter.type == ITER_IOVEC &&
+           msg->msg_iter.nr_segs == 1 &&
            msg->msg_iter.iov->iov_base == NULL) {
                err = netlink_mmap_sendmsg(sk, msg, dst_portid, dst_group,
                                           &scm);