net: rework recvmsg handler msg_name and msg_namelen logic
authorHannes Frederic Sowa <hannes@stressinduktion.org>
Thu, 21 Nov 2013 02:14:22 +0000 (03:14 +0100)
committerWilly Tarreau <w@1wt.eu>
Mon, 19 May 2014 05:54:00 +0000 (07:54 +0200)
CVE-2013-7266

BugLink: http://bugs.launchpad.net/bugs/1267081
This patch now always passes msg->msg_namelen as 0. recvmsg handlers must
set msg_namelen to the proper size <= sizeof(struct sockaddr_storage)
to return msg_name to the user.

This prevents numerous uninitialized memory leaks we had in the
recvmsg handlers and makes it harder for new code to accidentally leak
uninitialized memory.

Optimize for the case recvfrom is called with NULL as address. We don't
need to copy the address at all, so set it to NULL before invoking the
recvmsg handler. We can do so, because all the recvmsg handlers must
cope with the case a plain read() is called on them. read() also sets
msg_name to NULL.

Also document these changes in include/linux/net.h as suggested by David
Miller.

Changes since RFC:

Set msg->msg_name = NULL if user specified a NULL in msg_name but had a
non-null msg_namelen in verify_iovec/verify_compat_iovec. This doesn't
affect sendto as it would bail out earlier while trying to copy-in the
address. It also more naturally reflects the logic by the callers of
verify_iovec.

With this change in place I could remove "
if (!uaddr || msg_sys->msg_namelen == 0)
msg->msg_name = NULL
".

This change does not alter the user visible error logic as we ignore
msg_namelen as long as msg_name is NULL.

Also remove two unnecessary curly brackets in ___sys_recvmsg and change
comments to netdev style.

Cc: David Miller <davem@davemloft.net>
Suggested-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
(back ported from commit f3d3342602f8bcbf37d7c46641cb9bca7618eb1c)
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
Acked-by: Andy Whitcroft <andy.whitcroft@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
Signed-off-by: Willy Tarreau <w@1wt.eu>
27 files changed:
drivers/isdn/mISDN/socket.c
drivers/net/pppoe.c
drivers/net/pppol2tp.c
include/linux/net.h
net/appletalk/ddp.c
net/atm/common.c
net/ax25/af_ax25.c
net/bluetooth/af_bluetooth.c
net/bluetooth/hci_sock.c
net/bluetooth/rfcomm/sock.c
net/compat.c
net/core/iovec.c
net/ipx/af_ipx.c
net/irda/af_irda.c
net/iucv/af_iucv.c
net/key/af_key.c
net/llc/af_llc.c
net/netlink/af_netlink.c
net/netrom/af_netrom.c
net/packet/af_packet.c
net/rds/recv.c
net/rose/af_rose.c
net/rxrpc/ar-recvmsg.c
net/socket.c
net/tipc/socket.c
net/unix/af_unix.c
net/x25/af_x25.c

index feb0fa45b664b7f30f843d8097fc47013be8adce..db69cb47a2d6b917cc5cf1e8e74426e9f91964a9 100644 (file)
@@ -115,7 +115,6 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 {
        struct sk_buff          *skb;
        struct sock             *sk = sock->sk;
-       struct sockaddr_mISDN   *maddr;
 
        int             copied, err;
 
@@ -133,9 +132,9 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
        if (!skb)
                return err;
 
-       if (msg->msg_namelen >= sizeof(struct sockaddr_mISDN)) {
-               msg->msg_namelen = sizeof(struct sockaddr_mISDN);
-               maddr = (struct sockaddr_mISDN *)msg->msg_name;
+       if (msg->msg_name) {
+               struct sockaddr_mISDN *maddr = msg->msg_name;
+
                maddr->family = AF_ISDN;
                maddr->dev = _pms(sk)->dev->id;
                if ((sk->sk_protocol == ISDN_P_LAPD_TE) ||
@@ -148,11 +147,7 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
                        maddr->sapi = _pms(sk)->ch.addr & 0xFF;
                        maddr->tei =  (_pms(sk)->ch.addr >> 8) & 0xFF;
                }
-       } else {
-               if (msg->msg_namelen)
-                       printk(KERN_WARNING "%s: too small namelen %d\n",
-                           __func__, msg->msg_namelen);
-               msg->msg_namelen = 0;
+               msg->msg_namelen = sizeof(*maddr);
        }
 
        copied = skb->len + MISDN_HEADER_LEN;
index 2559991eea6a59e23a88837a897cf8e8dad7cc0a..343fd1ead9a4a29d809650b7c5416858adb07df0 100644 (file)
@@ -992,8 +992,6 @@ static int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock,
        if (error < 0)
                goto end;
 
-       m->msg_namelen = 0;
-
        if (skb) {
                total_len = min_t(size_t, total_len, skb->len);
                error = skb_copy_datagram_iovec(skb, 0, m->msg_iov, total_len);
index 92359019991af5aa91497a322852dc16653d635a..4cdc1cf9fb0fef66ab57394b13687b12672fdaf3 100644 (file)
@@ -829,8 +829,6 @@ static int pppol2tp_recvmsg(struct kiocb *iocb, struct socket *sock,
        if (sk->sk_state & PPPOX_BOUND)
                goto end;
 
-       msg->msg_namelen = 0;
-
        err = 0;
        skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
                                flags & MSG_DONTWAIT, &err);
index 529a0931711da5875cc70e88953dbe9621afd5d3..e40cbccc34e82684beb05166619b8ee86fccf09c 100644 (file)
@@ -187,6 +187,14 @@ struct proto_ops {
                                      int optname, char __user *optval, int __user *optlen);
        int             (*sendmsg)   (struct kiocb *iocb, struct socket *sock,
                                      struct msghdr *m, size_t total_len);
+       /* Notes for implementing recvmsg:
+        * ===============================
+        * msg->msg_namelen should get updated by the recvmsg handlers
+        * iff msg_name != NULL. It is by default 0 to prevent
+        * returning uninitialized memory to user space.  The recvfrom
+        * handlers can assume that msg.msg_name is either NULL or has
+        * a minimum size of sizeof(struct sockaddr_storage).
+        */
        int             (*recvmsg)   (struct kiocb *iocb, struct socket *sock,
                                      struct msghdr *m, size_t total_len,
                                      int flags);
index b1a4290996b511ebc644e86ab9b7aeb693e74db8..5eae3606f32ff46acccba41fe98fd173c3531ab0 100644 (file)
@@ -1703,7 +1703,6 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
                         size_t size, int flags)
 {
        struct sock *sk = sock->sk;
-       struct sockaddr_at *sat = (struct sockaddr_at *)msg->msg_name;
        struct ddpehdr *ddp;
        int copied = 0;
        int offset = 0;
@@ -1728,14 +1727,13 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
        }
        err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copied);
 
-       if (!err) {
-               if (sat) {
-                       sat->sat_family      = AF_APPLETALK;
-                       sat->sat_port        = ddp->deh_sport;
-                       sat->sat_addr.s_node = ddp->deh_snode;
-                       sat->sat_addr.s_net  = ddp->deh_snet;
-               }
-               msg->msg_namelen = sizeof(*sat);
+       if (!err && msg->msg_name) {
+               struct sockaddr_at *sat = msg->msg_name;
+               sat->sat_family      = AF_APPLETALK;
+               sat->sat_port        = ddp->deh_sport;
+               sat->sat_addr.s_node = ddp->deh_snode;
+               sat->sat_addr.s_net  = ddp->deh_snet;
+               msg->msg_namelen     = sizeof(*sat);
        }
 
        skb_free_datagram(sk, skb);     /* Free the datagram. */
index 65737b81059e8e0248d19f36d6fa2d0fd39be6fc..0baf05e8d34b52bb7dbb16b0fc21bf26d13fefb0 100644 (file)
@@ -473,8 +473,6 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
        struct sk_buff *skb;
        int copied, error = -EINVAL;
 
-       msg->msg_namelen = 0;
-
        if (sock->state != SS_CONNECTED)
                return -ENOTCONN;
        if (flags & ~MSG_DONTWAIT)              /* only handle MSG_DONTWAIT */
index 8613bd1ddabe8c3648249477557da749b91dec38..6b9d62b5d820536937a43d083bc88ba9d36981db 100644 (file)
@@ -1648,11 +1648,11 @@ static int ax25_recvmsg(struct kiocb *iocb, struct socket *sock,
 
        skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
 
-       if (msg->msg_namelen != 0) {
-               struct sockaddr_ax25 *sax = (struct sockaddr_ax25 *)msg->msg_name;
+       if (msg->msg_name) {
                ax25_digi digi;
                ax25_address src;
                const unsigned char *mac = skb_mac_header(skb);
+               struct sockaddr_ax25 *sax = msg->msg_name;
 
                memset(sax, 0, sizeof(struct full_sockaddr_ax25));
                ax25_addr_parse(mac + 1, skb->data - mac - 1, &src, NULL,
index d7239ddd6e20a01dcee1992dc679e0ee421723bd..143b8a7c1c475856309e239fddb8352d79039889 100644 (file)
@@ -240,8 +240,6 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
        if (flags & (MSG_OOB))
                return -EOPNOTSUPP;
 
-       msg->msg_namelen = 0;
-
        if (!(skb = skb_recv_datagram(sk, flags, noblock, &err))) {
                if (sk->sk_shutdown & RCV_SHUTDOWN)
                        return 0;
index 45caaaa4ace403950886bad26e0a44249dab612c..0e0f517d84d832c102b624528f6179a8ddabc144 100644 (file)
@@ -370,8 +370,6 @@ static int hci_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
        if (!(skb = skb_recv_datagram(sk, flags, noblock, &err)))
                return err;
 
-       msg->msg_namelen = 0;
-
        copied = skb->len;
        if (len < copied) {
                msg->msg_flags |= MSG_TRUNC;
index 1db0132f4965d8f3cfcf0c689acfe8beda26853d..3fabaad011c7bd5244387d5c4b92cdb52783feff 100644 (file)
@@ -652,15 +652,12 @@ static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
 
        if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
                rfcomm_dlc_accept(d);
-               msg->msg_namelen = 0;
                return 0;
        }
 
        if (flags & MSG_OOB)
                return -EOPNOTSUPP;
 
-       msg->msg_namelen = 0;
-
        BT_DBG("sk %p size %zu", sk, size);
 
        lock_sock(sk);
index da3d0fce433a733ead1fcf3e015fdd8580cf72a4..d325d16f8eaab6282dccb50124baa3afc781abb4 100644 (file)
@@ -91,7 +91,8 @@ int verify_compat_iovec(struct msghdr *kern_msg, struct iovec *kern_iov,
                        if (err < 0)
                                return err;
                }
-               kern_msg->msg_name = kern_address;
+               if (kern_msg->msg_name)
+                       kern_msg->msg_name = kern_address;
        } else
                kern_msg->msg_name = NULL;
 
index f911e665a7dbb2eb43981603439381782d98df8c..39369e90c9fc0db482cb87539f40384eb3c07c92 100644 (file)
@@ -47,7 +47,8 @@ int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address,
                        if (err < 0)
                                return err;
                }
-               m->msg_name = address;
+               if (m->msg_name)
+                       m->msg_name = address;
        } else {
                m->msg_name = NULL;
        }
index 66c7a20011f36b3147bb66c5169f5c292236f597..25931b3752b6a2117b8653452163122104d614d5 100644 (file)
@@ -1808,8 +1808,6 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
        if (skb->tstamp.tv64)
                sk->sk_stamp = skb->tstamp;
 
-       msg->msg_namelen = sizeof(*sipx);
-
        if (sipx) {
                sipx->sipx_family       = AF_IPX;
                sipx->sipx_port         = ipx->ipx_source.sock;
@@ -1817,6 +1815,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
                sipx->sipx_network      = IPX_SKB_CB(skb)->ipx_source_net;
                sipx->sipx_type         = ipx->ipx_type;
                sipx->sipx_zero         = 0;
+               msg->msg_namelen        = sizeof(*sipx);
        }
        rc = copied;
 
index bfb325de67cf1c647bbd691f9f59c25e9be58286..7cb7613d2ec7fd60f1285de44906350563bd3c3e 100644 (file)
@@ -1338,8 +1338,6 @@ static int irda_recvmsg_dgram(struct kiocb *iocb, struct socket *sock,
        if ((err = sock_error(sk)) < 0)
                return err;
 
-       msg->msg_namelen = 0;
-
        skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
                                flags & MSG_DONTWAIT, &err);
        if (!skb)
@@ -1402,8 +1400,6 @@ static int irda_recvmsg_stream(struct kiocb *iocb, struct socket *sock,
        target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
        timeo = sock_rcvtimeo(sk, noblock);
 
-       msg->msg_namelen = 0;
-
        do {
                int chunk;
                struct sk_buff *skb = skb_dequeue(&sk->sk_receive_queue);
index f605b238bd6fda8845b114c70e2e352c3f5a2ae4..bada1b9c670bd555fa10833165326492762b3d97 100644 (file)
@@ -1160,8 +1160,6 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
        struct sk_buff *skb, *rskb, *cskb;
        int err = 0;
 
-       msg->msg_namelen = 0;
-
        if ((sk->sk_state == IUCV_DISCONN || sk->sk_state == IUCV_SEVERED) &&
            skb_queue_empty(&iucv->backlog_skb_q) &&
            skb_queue_empty(&sk->sk_receive_queue) &&
index 3f55faae3fb0569a31ef925b07f283145e5d93e2..3e5d0dceb9957744051535ed33b5ea15076d5fc4 100644 (file)
@@ -3597,7 +3597,6 @@ static int pfkey_recvmsg(struct kiocb *kiocb,
        if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT))
                goto out;
 
-       msg->msg_namelen = 0;
        skb = skb_recv_datagram(sk, flags, flags & MSG_DONTWAIT, &err);
        if (skb == NULL)
                goto out;
index 8a814a59fed1e9b03c321484d147adc6db6fd0ef..606b6adac1cad23519439dc29860ef55e029333f 100644 (file)
@@ -674,8 +674,6 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
        int target;     /* Read at least this many bytes */
        long timeo;
 
-       msg->msg_namelen = 0;
-
        lock_sock(sk);
        copied = -ENOTCONN;
        if (unlikely(sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_LISTEN))
index fc91ff6907cb4f715fc0e47f55e8629718ea2cf4..39a6d5d7afcf03426bfd4247fed796e1e0f83479 100644 (file)
@@ -1400,8 +1400,6 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
        }
 #endif
 
-       msg->msg_namelen = 0;
-
        copied = data_skb->len;
        if (len < copied) {
                msg->msg_flags |= MSG_TRUNC;
index 7a834952f67fe75f72558b7e3c8477bc8ac259a6..ad1ec1b9f22f0b72c6f56d726fe4dfa8ff5d5191 100644 (file)
@@ -1184,10 +1184,9 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock,
                sax->sax25_family = AF_NETROM;
                skb_copy_from_linear_data_offset(skb, 7, sax->sax25_call.ax25_call,
                              AX25_ADDR_LEN);
+               msg->msg_namelen = sizeof(*sax);
        }
 
-       msg->msg_namelen = sizeof(*sax);
-
        skb_free_datagram(sk, skb);
 
        release_sock(sk);
index f084e01b80895b44675621c312d39546968f1435..06707d0538b07e69870b987e6f26719616744d50 100644 (file)
@@ -1423,7 +1423,6 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
        struct sock *sk = sock->sk;
        struct sk_buff *skb;
        int copied, err;
-       struct sockaddr_ll *sll;
 
        err = -EINVAL;
        if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT))
@@ -1455,22 +1454,10 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
        if (skb == NULL)
                goto out;
 
-       /*
-        *      If the address length field is there to be filled in, we fill
-        *      it in now.
+       /* You lose any data beyond the buffer you gave. If it worries
+        * a user program they can ask the device for its MTU
+        * anyway.
         */
-
-       sll = &PACKET_SKB_CB(skb)->sa.ll;
-       if (sock->type == SOCK_PACKET)
-               msg->msg_namelen = sizeof(struct sockaddr_pkt);
-       else
-               msg->msg_namelen = sll->sll_halen + offsetof(struct sockaddr_ll, sll_addr);
-
-       /*
-        *      You lose any data beyond the buffer you gave. If it worries a
-        *      user program they can ask the device for its MTU anyway.
-        */
-
        copied = skb->len;
        if (copied > len) {
                copied = len;
@@ -1483,9 +1470,20 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
 
        sock_recv_timestamp(msg, sk, skb);
 
-       if (msg->msg_name)
+       if (msg->msg_name) {
+               /* If the address length field is there to be filled
+                * in, we fill it in now.
+                */
+               if (sock->type == SOCK_PACKET) {
+                       msg->msg_namelen = sizeof(struct sockaddr_pkt);
+               } else {
+                       struct sockaddr_ll *sll = &PACKET_SKB_CB(skb)->sa.ll;
+                       msg->msg_namelen = sll->sll_halen +
+                               offsetof(struct sockaddr_ll, sll_addr);
+               }
                memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa,
                       msg->msg_namelen);
+       }
 
        if (pkt_sk(sk)->auxdata) {
                struct tpacket_auxdata aux;
index c45a881cf576b1946d5684ddde809466ef31b29a..a11cab901d271a526b1df157a60a5d05282a7a89 100644 (file)
@@ -410,8 +410,6 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
 
        rdsdebug("size %zu flags 0x%x timeo %ld\n", size, msg_flags, timeo);
 
-       msg->msg_namelen = 0;
-
        if (msg_flags & MSG_OOB)
                goto out;
 
index 2984999dc59e1772daef3dc6f6cd5532e7ffb7d5..08a86f62f5bbd8384cd6c3b82a3aee885188ca9b 100644 (file)
@@ -1238,7 +1238,6 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock,
 {
        struct sock *sk = sock->sk;
        struct rose_sock *rose = rose_sk(sk);
-       struct sockaddr_rose *srose = (struct sockaddr_rose *)msg->msg_name;
        size_t copied;
        unsigned char *asmptr;
        struct sk_buff *skb;
@@ -1274,8 +1273,11 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock,
 
        skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
 
-       if (srose != NULL) {
-               memset(srose, 0, msg->msg_namelen);
+       if (msg->msg_name) {
+               struct sockaddr_rose *srose;
+
+               memset(msg->msg_name, 0, sizeof(struct full_sockaddr_rose));
+               srose = msg->msg_name;
                srose->srose_family = AF_ROSE;
                srose->srose_addr   = rose->dest_addr;
                srose->srose_call   = rose->dest_call;
index a39bf97f8830703cf1a6c5e23367727532e26efb..d5630d915d9c678cbd8013079e2097e0850d9775 100644 (file)
@@ -142,10 +142,13 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock,
 
                /* copy the peer address and timestamp */
                if (!continue_call) {
-                       if (msg->msg_name && msg->msg_namelen > 0)
+                       if (msg->msg_name) {
+                               size_t len =
+                                       sizeof(call->conn->trans->peer->srx);
                                memcpy(msg->msg_name,
-                                      &call->conn->trans->peer->srx,
-                                      sizeof(call->conn->trans->peer->srx));
+                                      &call->conn->trans->peer->srx, len);
+                               msg->msg_namelen = len;
+                       }
                        sock_recv_timestamp(msg, &rx->sk, skb);
                }
 
index 9f8cd744f0b02954d34c65e043a03cc822309f26..06e8f3d1db2f68906a869d49e5ad815ce5aeaea9 100644 (file)
@@ -1744,8 +1744,10 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
        msg.msg_iov = &iov;
        iov.iov_len = size;
        iov.iov_base = ubuf;
-       msg.msg_name = (struct sockaddr *)&address;
-       msg.msg_namelen = sizeof(address);
+       /* Save some cycles and don't copy the address if not needed */
+       msg.msg_name = addr ? (struct sockaddr *)&address : NULL;
+       /* We assume all kernel code knows the size of sockaddr_storage */
+       msg.msg_namelen = 0;
        if (sock->file->f_flags & O_NONBLOCK)
                flags |= MSG_DONTWAIT;
        err = sock_recvmsg(sock, &msg, size, flags);
@@ -2033,18 +2035,16 @@ SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg,
                        goto out_put;
        }
 
-       /*
-        *      Save the user-mode address (verify_iovec will change the
-        *      kernel msghdr to use the kernel address space)
+       /* Save the user-mode address (verify_iovec will change the
+        * kernel msghdr to use the kernel address space)
         */
-
        uaddr = (__force void __user *)msg_sys.msg_name;
        uaddr_len = COMPAT_NAMELEN(msg);
-       if (MSG_CMSG_COMPAT & flags) {
+       if (MSG_CMSG_COMPAT & flags)
                err = verify_compat_iovec(&msg_sys, iov,
                                          (struct sockaddr *)&addr,
                                          VERIFY_WRITE);
-       else
+       else
                err = verify_iovec(&msg_sys, iov,
                                   (struct sockaddr *)&addr,
                                   VERIFY_WRITE);
@@ -2055,6 +2055,9 @@ SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg,
        cmsg_ptr = (unsigned long)msg_sys.msg_control;
        msg_sys.msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT);
 
+       /* We assume all kernel code knows the size of sockaddr_storage */
+       msg_sys.msg_namelen = 0;
+
        if (sock->file->f_flags & O_NONBLOCK)
                flags |= MSG_DONTWAIT;
        err = sock_recvmsg(sock, &msg_sys, total_len, flags);
index eccb86b9c37033406b90c5d6d08332a1a9119ca3..124f1a29e63d723c7b64e0094bca5dc4037cedd2 100644 (file)
@@ -917,9 +917,6 @@ static int recv_msg(struct kiocb *iocb, struct socket *sock,
                goto exit;
        }
 
-       /* will be updated in set_orig_addr() if needed */
-       m->msg_namelen = 0;
-
 restart:
 
        /* Look for a message in receive queue; wait if necessary */
@@ -1053,9 +1050,6 @@ static int recv_stream(struct kiocb *iocb, struct socket *sock,
                goto exit;
        }
 
-       /* will be updated in set_orig_addr() if needed */
-       m->msg_namelen = 0;
-
 restart:
 
        /* Look for a message in receive queue; wait if necessary */
index d146b76840b5090c5e7f38379648806435c2ce78..bb0b0082ee023af3481f4592dba71254691530c4 100644 (file)
@@ -1682,7 +1682,6 @@ static void unix_copy_addr(struct msghdr *msg, struct sock *sk)
 {
        struct unix_sock *u = unix_sk(sk);
 
-       msg->msg_namelen = 0;
        if (u->addr) {
                msg->msg_namelen = u->addr->len;
                memcpy(msg->msg_name, u->addr->name, u->addr->len);
@@ -1705,8 +1704,6 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
        if (flags&MSG_OOB)
                goto out;
 
-       msg->msg_namelen = 0;
-
        mutex_lock(&u->readlock);
 
        skb = skb_recv_datagram(sk, flags, noblock, &err);
@@ -1832,8 +1829,6 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
        target = sock_rcvlowat(sk, flags&MSG_WAITALL, size);
        timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT);
 
-       msg->msg_namelen = 0;
-
        /* Lock the socket to prevent queue disordering
         * while sleeps in memcpy_tomsg
         */
index 2e9e30025d60edac9b90e644a0f74d267ce6c6db..40c447fc20aae4322d1809e5e4d3bcfa1974e3c8 100644 (file)
@@ -1294,10 +1294,9 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,
        if (sx25) {
                sx25->sx25_family = AF_X25;
                sx25->sx25_addr   = x25->dest_addr;
+               msg->msg_namelen = sizeof(*sx25);
        }
 
-       msg->msg_namelen = sizeof(struct sockaddr_x25);
-
        lock_sock(sk);
        x25_check_rbuf(sk);
        release_sock(sk);