Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: rework recvmsg handler msg_name and msg_namelen logic

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>

authored by

Hannes Frederic Sowa and committed by
David S. Miller
f3d33426 f8730420

+67 -115
-2
crypto/algif_hash.c
··· 161 161 else if (len < ds) 162 162 msg->msg_flags |= MSG_TRUNC; 163 163 164 - msg->msg_namelen = 0; 165 - 166 164 lock_sock(sk); 167 165 if (ctx->more) { 168 166 ctx->more = 0;
-1
crypto/algif_skcipher.c
··· 432 432 long copied = 0; 433 433 434 434 lock_sock(sk); 435 - msg->msg_namelen = 0; 436 435 for (iov = msg->msg_iov, iovlen = msg->msg_iovlen; iovlen > 0; 437 436 iovlen--, iov++) { 438 437 unsigned long seglen = iov->iov_len;
+4 -9
drivers/isdn/mISDN/socket.c
··· 117 117 { 118 118 struct sk_buff *skb; 119 119 struct sock *sk = sock->sk; 120 - struct sockaddr_mISDN *maddr; 121 120 122 121 int copied, err; 123 122 ··· 134 135 if (!skb) 135 136 return err; 136 137 137 - if (msg->msg_namelen >= sizeof(struct sockaddr_mISDN)) { 138 - msg->msg_namelen = sizeof(struct sockaddr_mISDN); 139 - maddr = (struct sockaddr_mISDN *)msg->msg_name; 138 + if (msg->msg_name) { 139 + struct sockaddr_mISDN *maddr = msg->msg_name; 140 + 140 141 maddr->family = AF_ISDN; 141 142 maddr->dev = _pms(sk)->dev->id; 142 143 if ((sk->sk_protocol == ISDN_P_LAPD_TE) || ··· 149 150 maddr->sapi = _pms(sk)->ch.addr & 0xFF; 150 151 maddr->tei = (_pms(sk)->ch.addr >> 8) & 0xFF; 151 152 } 152 - } else { 153 - if (msg->msg_namelen) 154 - printk(KERN_WARNING "%s: too small namelen %d\n", 155 - __func__, msg->msg_namelen); 156 - msg->msg_namelen = 0; 153 + msg->msg_namelen = sizeof(*maddr); 157 154 } 158 155 159 156 copied = skb->len + MISDN_HEADER_LEN;
-2
drivers/net/ppp/pppoe.c
··· 979 979 if (error < 0) 980 980 goto end; 981 981 982 - m->msg_namelen = 0; 983 - 984 982 if (skb) { 985 983 total_len = min_t(size_t, total_len, skb->len); 986 984 error = skb_copy_datagram_iovec(skb, 0, m->msg_iov, total_len);
+8
include/linux/net.h
··· 164 164 #endif 165 165 int (*sendmsg) (struct kiocb *iocb, struct socket *sock, 166 166 struct msghdr *m, size_t total_len); 167 + /* Notes for implementing recvmsg: 168 + * =============================== 169 + * msg->msg_namelen should get updated by the recvmsg handlers 170 + * iff msg_name != NULL. It is by default 0 to prevent 171 + * returning uninitialized memory to user space. The recvfrom 172 + * handlers can assume that msg.msg_name is either NULL or has 173 + * a minimum size of sizeof(struct sockaddr_storage). 174 + */ 167 175 int (*recvmsg) (struct kiocb *iocb, struct socket *sock, 168 176 struct msghdr *m, size_t total_len, 169 177 int flags);
+7 -9
net/appletalk/ddp.c
··· 1735 1735 size_t size, int flags) 1736 1736 { 1737 1737 struct sock *sk = sock->sk; 1738 - struct sockaddr_at *sat = (struct sockaddr_at *)msg->msg_name; 1739 1738 struct ddpehdr *ddp; 1740 1739 int copied = 0; 1741 1740 int offset = 0; ··· 1763 1764 } 1764 1765 err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copied); 1765 1766 1766 - if (!err) { 1767 - if (sat) { 1768 - sat->sat_family = AF_APPLETALK; 1769 - sat->sat_port = ddp->deh_sport; 1770 - sat->sat_addr.s_node = ddp->deh_snode; 1771 - sat->sat_addr.s_net = ddp->deh_snet; 1772 - } 1773 - msg->msg_namelen = sizeof(*sat); 1767 + if (!err && msg->msg_name) { 1768 + struct sockaddr_at *sat = msg->msg_name; 1769 + sat->sat_family = AF_APPLETALK; 1770 + sat->sat_port = ddp->deh_sport; 1771 + sat->sat_addr.s_node = ddp->deh_snode; 1772 + sat->sat_addr.s_net = ddp->deh_snet; 1773 + msg->msg_namelen = sizeof(*sat); 1774 1774 } 1775 1775 1776 1776 skb_free_datagram(sk, skb); /* Free the datagram. */
-2
net/atm/common.c
··· 531 531 struct sk_buff *skb; 532 532 int copied, error = -EINVAL; 533 533 534 - msg->msg_namelen = 0; 535 - 536 534 if (sock->state != SS_CONNECTED) 537 535 return -ENOTCONN; 538 536
+2 -2
net/ax25/af_ax25.c
··· 1636 1636 1637 1637 skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); 1638 1638 1639 - if (msg->msg_namelen != 0) { 1640 - struct sockaddr_ax25 *sax = (struct sockaddr_ax25 *)msg->msg_name; 1639 + if (msg->msg_name) { 1641 1640 ax25_digi digi; 1642 1641 ax25_address src; 1643 1642 const unsigned char *mac = skb_mac_header(skb); 1643 + struct sockaddr_ax25 *sax = msg->msg_name; 1644 1644 1645 1645 memset(sax, 0, sizeof(struct full_sockaddr_ax25)); 1646 1646 ax25_addr_parse(mac + 1, skb->data - mac - 1, &src, NULL,
+2 -7
net/bluetooth/af_bluetooth.c
··· 224 224 225 225 skb = skb_recv_datagram(sk, flags, noblock, &err); 226 226 if (!skb) { 227 - if (sk->sk_shutdown & RCV_SHUTDOWN) { 228 - msg->msg_namelen = 0; 227 + if (sk->sk_shutdown & RCV_SHUTDOWN) 229 228 return 0; 230 - } 229 + 231 230 return err; 232 231 } 233 232 ··· 244 245 if (bt_sk(sk)->skb_msg_name) 245 246 bt_sk(sk)->skb_msg_name(skb, msg->msg_name, 246 247 &msg->msg_namelen); 247 - else 248 - msg->msg_namelen = 0; 249 248 } 250 249 251 250 skb_free_datagram(sk, skb); ··· 291 294 292 295 if (flags & MSG_OOB) 293 296 return -EOPNOTSUPP; 294 - 295 - msg->msg_namelen = 0; 296 297 297 298 BT_DBG("sk %p size %zu", sk, size); 298 299
-2
net/bluetooth/hci_sock.c
··· 856 856 if (!skb) 857 857 return err; 858 858 859 - msg->msg_namelen = 0; 860 - 861 859 copied = skb->len; 862 860 if (len < copied) { 863 861 msg->msg_flags |= MSG_TRUNC;
-1
net/bluetooth/rfcomm/sock.c
··· 615 615 616 616 if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) { 617 617 rfcomm_dlc_accept(d); 618 - msg->msg_namelen = 0; 619 618 return 0; 620 619 } 621 620
-1
net/bluetooth/sco.c
··· 711 711 test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) { 712 712 sco_conn_defer_accept(pi->conn->hcon, pi->setting); 713 713 sk->sk_state = BT_CONFIG; 714 - msg->msg_namelen = 0; 715 714 716 715 release_sock(sk); 717 716 return 0;
-4
net/caif/caif_socket.c
··· 286 286 if (m->msg_flags&MSG_OOB) 287 287 goto read_error; 288 288 289 - m->msg_namelen = 0; 290 - 291 289 skb = skb_recv_datagram(sk, flags, 0 , &ret); 292 290 if (!skb) 293 291 goto read_error; ··· 358 360 err = -EOPNOTSUPP; 359 361 if (flags&MSG_OOB) 360 362 goto out; 361 - 362 - msg->msg_namelen = 0; 363 363 364 364 /* 365 365 * Lock the socket to prevent queue disordering
+2 -1
net/compat.c
··· 93 93 if (err < 0) 94 94 return err; 95 95 } 96 - kern_msg->msg_name = kern_address; 96 + if (kern_msg->msg_name) 97 + kern_msg->msg_name = kern_address; 97 98 } else 98 99 kern_msg->msg_name = NULL; 99 100
+2 -1
net/core/iovec.c
··· 48 48 if (err < 0) 49 49 return err; 50 50 } 51 - m->msg_name = address; 51 + if (m->msg_name) 52 + m->msg_name = address; 52 53 } else { 53 54 m->msg_name = NULL; 54 55 }
+1 -2
net/ipx/af_ipx.c
··· 1823 1823 if (skb->tstamp.tv64) 1824 1824 sk->sk_stamp = skb->tstamp; 1825 1825 1826 - msg->msg_namelen = sizeof(*sipx); 1827 - 1828 1826 if (sipx) { 1829 1827 sipx->sipx_family = AF_IPX; 1830 1828 sipx->sipx_port = ipx->ipx_source.sock; ··· 1830 1832 sipx->sipx_network = IPX_SKB_CB(skb)->ipx_source_net; 1831 1833 sipx->sipx_type = ipx->ipx_type; 1832 1834 sipx->sipx_zero = 0; 1835 + msg->msg_namelen = sizeof(*sipx); 1833 1836 } 1834 1837 rc = copied; 1835 1838
-4
net/irda/af_irda.c
··· 1385 1385 1386 1386 IRDA_DEBUG(4, "%s()\n", __func__); 1387 1387 1388 - msg->msg_namelen = 0; 1389 - 1390 1388 skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, 1391 1389 flags & MSG_DONTWAIT, &err); 1392 1390 if (!skb) ··· 1448 1450 err = 0; 1449 1451 target = sock_rcvlowat(sk, flags & MSG_WAITALL, size); 1450 1452 timeo = sock_rcvtimeo(sk, noblock); 1451 - 1452 - msg->msg_namelen = 0; 1453 1453 1454 1454 do { 1455 1455 int chunk;
-2
net/iucv/af_iucv.c
··· 1324 1324 int err = 0; 1325 1325 u32 offset; 1326 1326 1327 - msg->msg_namelen = 0; 1328 - 1329 1327 if ((sk->sk_state == IUCV_DISCONN) && 1330 1328 skb_queue_empty(&iucv->backlog_skb_q) && 1331 1329 skb_queue_empty(&sk->sk_receive_queue) &&
-1
net/key/af_key.c
··· 3616 3616 if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT)) 3617 3617 goto out; 3618 3618 3619 - msg->msg_namelen = 0; 3620 3619 skb = skb_recv_datagram(sk, flags, flags & MSG_DONTWAIT, &err); 3621 3620 if (skb == NULL) 3622 3621 goto out;
-2
net/l2tp/l2tp_ppp.c
··· 197 197 if (sk->sk_state & PPPOX_BOUND) 198 198 goto end; 199 199 200 - msg->msg_namelen = 0; 201 - 202 200 err = 0; 203 201 skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, 204 202 flags & MSG_DONTWAIT, &err);
-2
net/llc/af_llc.c
··· 720 720 int target; /* Read at least this many bytes */ 721 721 long timeo; 722 722 723 - msg->msg_namelen = 0; 724 - 725 723 lock_sock(sk); 726 724 copied = -ENOTCONN; 727 725 if (unlikely(sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_LISTEN))
-2
net/netlink/af_netlink.c
··· 2335 2335 } 2336 2336 #endif 2337 2337 2338 - msg->msg_namelen = 0; 2339 - 2340 2338 copied = data_skb->len; 2341 2339 if (len < copied) { 2342 2340 msg->msg_flags |= MSG_TRUNC;
+1 -2
net/netrom/af_netrom.c
··· 1179 1179 sax->sax25_family = AF_NETROM; 1180 1180 skb_copy_from_linear_data_offset(skb, 7, sax->sax25_call.ax25_call, 1181 1181 AX25_ADDR_LEN); 1182 + msg->msg_namelen = sizeof(*sax); 1182 1183 } 1183 - 1184 - msg->msg_namelen = sizeof(*sax); 1185 1184 1186 1185 skb_free_datagram(sk, skb); 1187 1186
-2
net/nfc/llcp_sock.c
··· 807 807 808 808 pr_debug("%p %zu\n", sk, len); 809 809 810 - msg->msg_namelen = 0; 811 - 812 810 lock_sock(sk); 813 811 814 812 if (sk->sk_state == LLCP_CLOSED &&
-2
net/nfc/rawsock.c
··· 244 244 if (!skb) 245 245 return rc; 246 246 247 - msg->msg_namelen = 0; 248 - 249 247 copied = skb->len; 250 248 if (len < copied) { 251 249 msg->msg_flags |= MSG_TRUNC;
+15 -17
net/packet/af_packet.c
··· 2660 2660 struct sock *sk = sock->sk; 2661 2661 struct sk_buff *skb; 2662 2662 int copied, err; 2663 - struct sockaddr_ll *sll; 2664 2663 int vnet_hdr_len = 0; 2665 2664 2666 2665 err = -EINVAL; ··· 2743 2744 goto out_free; 2744 2745 } 2745 2746 2746 - /* 2747 - * If the address length field is there to be filled in, we fill 2748 - * it in now. 2747 + /* You lose any data beyond the buffer you gave. If it worries 2748 + * a user program they can ask the device for its MTU 2749 + * anyway. 2749 2750 */ 2750 - 2751 - sll = &PACKET_SKB_CB(skb)->sa.ll; 2752 - if (sock->type == SOCK_PACKET) 2753 - msg->msg_namelen = sizeof(struct sockaddr_pkt); 2754 - else 2755 - msg->msg_namelen = sll->sll_halen + offsetof(struct sockaddr_ll, sll_addr); 2756 - 2757 - /* 2758 - * You lose any data beyond the buffer you gave. If it worries a 2759 - * user program they can ask the device for its MTU anyway. 2760 - */ 2761 - 2762 2751 copied = skb->len; 2763 2752 if (copied > len) { 2764 2753 copied = len; ··· 2759 2772 2760 2773 sock_recv_ts_and_drops(msg, sk, skb); 2761 2774 2762 - if (msg->msg_name) 2775 + if (msg->msg_name) { 2776 + /* If the address length field is there to be filled 2777 + * in, we fill it in now. 2778 + */ 2779 + if (sock->type == SOCK_PACKET) { 2780 + msg->msg_namelen = sizeof(struct sockaddr_pkt); 2781 + } else { 2782 + struct sockaddr_ll *sll = &PACKET_SKB_CB(skb)->sa.ll; 2783 + msg->msg_namelen = sll->sll_halen + 2784 + offsetof(struct sockaddr_ll, sll_addr); 2785 + } 2763 2786 memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa, 2764 2787 msg->msg_namelen); 2788 + } 2765 2789 2766 2790 if (pkt_sk(sk)->auxdata) { 2767 2791 struct tpacket_auxdata aux;
-2
net/rds/recv.c
··· 410 410 411 411 rdsdebug("size %zu flags 0x%x timeo %ld\n", size, msg_flags, timeo); 412 412 413 - msg->msg_namelen = 0; 414 - 415 413 if (msg_flags & MSG_OOB) 416 414 goto out; 417 415
+5 -3
net/rose/af_rose.c
··· 1216 1216 { 1217 1217 struct sock *sk = sock->sk; 1218 1218 struct rose_sock *rose = rose_sk(sk); 1219 - struct sockaddr_rose *srose = (struct sockaddr_rose *)msg->msg_name; 1220 1219 size_t copied; 1221 1220 unsigned char *asmptr; 1222 1221 struct sk_buff *skb; ··· 1251 1252 1252 1253 skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); 1253 1254 1254 - if (srose != NULL) { 1255 - memset(srose, 0, msg->msg_namelen); 1255 + if (msg->msg_name) { 1256 + struct sockaddr_rose *srose; 1257 + 1258 + memset(msg->msg_name, 0, sizeof(struct full_sockaddr_rose)); 1259 + srose = msg->msg_name; 1256 1260 srose->srose_family = AF_ROSE; 1257 1261 srose->srose_addr = rose->dest_addr; 1258 1262 srose->srose_call = rose->dest_call;
+6 -3
net/rxrpc/ar-recvmsg.c
··· 143 143 144 144 /* copy the peer address and timestamp */ 145 145 if (!continue_call) { 146 - if (msg->msg_name && msg->msg_namelen > 0) 146 + if (msg->msg_name) { 147 + size_t len = 148 + sizeof(call->conn->trans->peer->srx); 147 149 memcpy(msg->msg_name, 148 - &call->conn->trans->peer->srx, 149 - sizeof(call->conn->trans->peer->srx)); 150 + &call->conn->trans->peer->srx, len); 151 + msg->msg_namelen = len; 152 + } 150 153 sock_recv_ts_and_drops(msg, &rx->sk, skb); 151 154 } 152 155
+11 -8
net/socket.c
··· 1840 1840 msg.msg_iov = &iov; 1841 1841 iov.iov_len = size; 1842 1842 iov.iov_base = ubuf; 1843 - msg.msg_name = (struct sockaddr *)&address; 1844 - msg.msg_namelen = sizeof(address); 1843 + /* Save some cycles and don't copy the address if not needed */ 1844 + msg.msg_name = addr ? (struct sockaddr *)&address : NULL; 1845 + /* We assume all kernel code knows the size of sockaddr_storage */ 1846 + msg.msg_namelen = 0; 1845 1847 if (sock->file->f_flags & O_NONBLOCK) 1846 1848 flags |= MSG_DONTWAIT; 1847 1849 err = sock_recvmsg(sock, &msg, size, flags); ··· 2223 2221 goto out; 2224 2222 } 2225 2223 2226 - /* 2227 - * Save the user-mode address (verify_iovec will change the 2228 - * kernel msghdr to use the kernel address space) 2224 + /* Save the user-mode address (verify_iovec will change the 2225 + * kernel msghdr to use the kernel address space) 2229 2226 */ 2230 - 2231 2227 uaddr = (__force void __user *)msg_sys->msg_name; 2232 2228 uaddr_len = COMPAT_NAMELEN(msg); 2233 - if (MSG_CMSG_COMPAT & flags) { 2229 + if (MSG_CMSG_COMPAT & flags) 2234 2230 err = verify_compat_iovec(msg_sys, iov, &addr, VERIFY_WRITE); 2235 - } else 2231 + else 2236 2232 err = verify_iovec(msg_sys, iov, &addr, VERIFY_WRITE); 2237 2233 if (err < 0) 2238 2234 goto out_freeiov; ··· 2238 2238 2239 2239 cmsg_ptr = (unsigned long)msg_sys->msg_control; 2240 2240 msg_sys->msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT); 2241 + 2242 + /* We assume all kernel code knows the size of sockaddr_storage */ 2243 + msg_sys->msg_namelen = 0; 2241 2244 2242 2245 if (sock->file->f_flags & O_NONBLOCK) 2243 2246 flags |= MSG_DONTWAIT;
-6
net/tipc/socket.c
··· 980 980 goto exit; 981 981 } 982 982 983 - /* will be updated in set_orig_addr() if needed */ 984 - m->msg_namelen = 0; 985 - 986 983 timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT); 987 984 restart: 988 985 ··· 1087 1090 res = -ENOTCONN; 1088 1091 goto exit; 1089 1092 } 1090 - 1091 - /* will be updated in set_orig_addr() if needed */ 1092 - m->msg_namelen = 0; 1093 1093 1094 1094 target = sock_rcvlowat(sk, flags & MSG_WAITALL, buf_len); 1095 1095 timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
-5
net/unix/af_unix.c
··· 1754 1754 { 1755 1755 struct unix_sock *u = unix_sk(sk); 1756 1756 1757 - msg->msg_namelen = 0; 1758 1757 if (u->addr) { 1759 1758 msg->msg_namelen = u->addr->len; 1760 1759 memcpy(msg->msg_name, u->addr->name, u->addr->len); ··· 1776 1777 err = -EOPNOTSUPP; 1777 1778 if (flags&MSG_OOB) 1778 1779 goto out; 1779 - 1780 - msg->msg_namelen = 0; 1781 1780 1782 1781 err = mutex_lock_interruptible(&u->readlock); 1783 1782 if (err) { ··· 1920 1923 1921 1924 target = sock_rcvlowat(sk, flags&MSG_WAITALL, size); 1922 1925 timeo = sock_rcvtimeo(sk, flags&MSG_DONTWAIT); 1923 - 1924 - msg->msg_namelen = 0; 1925 1926 1926 1927 /* Lock the socket to prevent queue disordering 1927 1928 * while sleeps in memcpy_tomsg
-2
net/vmw_vsock/af_vsock.c
··· 1662 1662 vsk = vsock_sk(sk); 1663 1663 err = 0; 1664 1664 1665 - msg->msg_namelen = 0; 1666 - 1667 1665 lock_sock(sk); 1668 1666 1669 1667 if (sk->sk_state != SS_CONNECTED) {
-2
net/vmw_vsock/vmci_transport.c
··· 1746 1746 if (flags & MSG_OOB || flags & MSG_ERRQUEUE) 1747 1747 return -EOPNOTSUPP; 1748 1748 1749 - msg->msg_namelen = 0; 1750 - 1751 1749 /* Retrieve the head sk_buff from the socket's receive queue. */ 1752 1750 err = 0; 1753 1751 skb = skb_recv_datagram(&vsk->sk, flags, noblock, &err);
+1 -2
net/x25/af_x25.c
··· 1340 1340 if (sx25) { 1341 1341 sx25->sx25_family = AF_X25; 1342 1342 sx25->sx25_addr = x25->dest_addr; 1343 + msg->msg_namelen = sizeof(*sx25); 1343 1344 } 1344 - 1345 - msg->msg_namelen = sizeof(struct sockaddr_x25); 1346 1345 1347 1346 x25_check_rbuf(sk); 1348 1347 rc = copied;