net: add build-time checks for msg->msg_name size

This is a follow-up patch to f3d3342602 ("net: rework recvmsg
handler msg_name and msg_namelen logic").

DECLARE_SOCKADDR validates that the structure we use for writing the
name information to is not larger than the buffer which is reserved
for msg->msg_name (which is 128 bytes). Also use DECLARE_SOCKADDR
consistently in sendmsg code paths.

Signed-off-by: Steffen Hurrle <steffen@hurrle.net>
Suggested-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Steffen Hurrle 2014-01-17 22:53:15 +01:00 committed by David S. Miller
parent ea02f9411d
commit 342dfc306f
34 changed files with 68 additions and 78 deletions

View File

@ -135,7 +135,7 @@ mISDN_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
return err; return err;
if (msg->msg_name) { if (msg->msg_name) {
struct sockaddr_mISDN *maddr = msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_mISDN *, maddr, msg->msg_name);
maddr->family = AF_ISDN; maddr->family = AF_ISDN;
maddr->dev = _pms(sk)->dev->id; maddr->dev = _pms(sk)->dev->id;
@ -179,7 +179,6 @@ mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct sk_buff *skb; struct sk_buff *skb;
int err = -ENOMEM; int err = -ENOMEM;
struct sockaddr_mISDN *maddr;
if (*debug & DEBUG_SOCKET) if (*debug & DEBUG_SOCKET)
printk(KERN_DEBUG "%s: len %d flags %x ch %d proto %x\n", printk(KERN_DEBUG "%s: len %d flags %x ch %d proto %x\n",
@ -214,7 +213,7 @@ mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
if (msg->msg_namelen >= sizeof(struct sockaddr_mISDN)) { if (msg->msg_namelen >= sizeof(struct sockaddr_mISDN)) {
/* if we have a address, we use it */ /* if we have a address, we use it */
maddr = (struct sockaddr_mISDN *)msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_mISDN *, maddr, msg->msg_name);
mISDN_HEAD_ID(skb) = maddr->channel; mISDN_HEAD_ID(skb) = maddr->channel;
} else { /* use default for L2 messages */ } else { /* use default for L2 messages */
if ((sk->sk_protocol == ISDN_P_LAPD_TE) || if ((sk->sk_protocol == ISDN_P_LAPD_TE) ||

View File

@ -1566,7 +1566,7 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct atalk_sock *at = at_sk(sk); struct atalk_sock *at = at_sk(sk);
struct sockaddr_at *usat = (struct sockaddr_at *)msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_at *, usat, msg->msg_name);
int flags = msg->msg_flags; int flags = msg->msg_flags;
int loopback = 0; int loopback = 0;
struct sockaddr_at local_satalk, gsat; struct sockaddr_at local_satalk, gsat;
@ -1764,7 +1764,7 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copied); err = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copied);
if (!err && msg->msg_name) { if (!err && msg->msg_name) {
struct sockaddr_at *sat = msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_at *, sat, msg->msg_name);
sat->sat_family = AF_APPLETALK; sat->sat_family = AF_APPLETALK;
sat->sat_port = ddp->deh_sport; sat->sat_port = ddp->deh_sport;
sat->sat_addr.s_node = ddp->deh_snode; sat->sat_addr.s_node = ddp->deh_snode;

View File

@ -1435,7 +1435,7 @@ out:
static int ax25_sendmsg(struct kiocb *iocb, struct socket *sock, static int ax25_sendmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t len) struct msghdr *msg, size_t len)
{ {
struct sockaddr_ax25 *usax = (struct sockaddr_ax25 *)msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_ax25 *, usax, msg->msg_name);
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct sockaddr_ax25 sax; struct sockaddr_ax25 sax;
struct sk_buff *skb; struct sk_buff *skb;
@ -1640,7 +1640,7 @@ static int ax25_recvmsg(struct kiocb *iocb, struct socket *sock,
ax25_digi digi; ax25_digi digi;
ax25_address src; ax25_address src;
const unsigned char *mac = skb_mac_header(skb); const unsigned char *mac = skb_mac_header(skb);
struct sockaddr_ax25 *sax = msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_ax25 *, sax, msg->msg_name);
memset(sax, 0, sizeof(struct full_sockaddr_ax25)); memset(sax, 0, sizeof(struct full_sockaddr_ax25));
ax25_addr_parse(mac + 1, skb->data - mac - 1, &src, NULL, ax25_addr_parse(mac + 1, skb->data - mac - 1, &src, NULL,

View File

@ -1413,7 +1413,7 @@ static void l2cap_sock_destruct(struct sock *sk)
static void l2cap_skb_msg_name(struct sk_buff *skb, void *msg_name, static void l2cap_skb_msg_name(struct sk_buff *skb, void *msg_name,
int *msg_namelen) int *msg_namelen)
{ {
struct sockaddr_l2 *la = (struct sockaddr_l2 *) msg_name; DECLARE_SOCKADDR(struct sockaddr_l2 *, la, msg_name);
memset(la, 0, sizeof(struct sockaddr_l2)); memset(la, 0, sizeof(struct sockaddr_l2));
la->l2_family = AF_BLUETOOTH; la->l2_family = AF_BLUETOOTH;

View File

@ -1256,8 +1256,7 @@ static int bcm_sendmsg(struct kiocb *iocb, struct socket *sock,
if (!ifindex && msg->msg_name) { if (!ifindex && msg->msg_name) {
/* no bound device as default => check msg_name */ /* no bound device as default => check msg_name */
struct sockaddr_can *addr = DECLARE_SOCKADDR(struct sockaddr_can *, addr, msg->msg_name);
(struct sockaddr_can *)msg->msg_name;
if (msg->msg_namelen < sizeof(*addr)) if (msg->msg_namelen < sizeof(*addr))
return -EINVAL; return -EINVAL;
@ -1568,6 +1567,7 @@ static int bcm_recvmsg(struct kiocb *iocb, struct socket *sock,
sock_recv_ts_and_drops(msg, sk, skb); sock_recv_ts_and_drops(msg, sk, skb);
if (msg->msg_name) { if (msg->msg_name) {
__sockaddr_check_size(sizeof(struct sockaddr_can));
msg->msg_namelen = sizeof(struct sockaddr_can); msg->msg_namelen = sizeof(struct sockaddr_can);
memcpy(msg->msg_name, skb->cb, msg->msg_namelen); memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
} }

View File

@ -675,8 +675,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct socket *sock,
int err; int err;
if (msg->msg_name) { if (msg->msg_name) {
struct sockaddr_can *addr = DECLARE_SOCKADDR(struct sockaddr_can *, addr, msg->msg_name);
(struct sockaddr_can *)msg->msg_name;
if (msg->msg_namelen < sizeof(*addr)) if (msg->msg_namelen < sizeof(*addr))
return -EINVAL; return -EINVAL;
@ -775,6 +774,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock,
sock_recv_ts_and_drops(msg, sk, skb); sock_recv_ts_and_drops(msg, sk, skb);
if (msg->msg_name) { if (msg->msg_name) {
__sockaddr_check_size(sizeof(struct sockaddr_can));
msg->msg_namelen = sizeof(struct sockaddr_can); msg->msg_namelen = sizeof(struct sockaddr_can);
memcpy(msg->msg_name, skb->cb, msg->msg_namelen); memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
} }

View File

@ -1808,6 +1808,7 @@ out:
rv = (flags & MSG_PEEK) ? -sk->sk_err : sock_error(sk); rv = (flags & MSG_PEEK) ? -sk->sk_err : sock_error(sk);
if ((rv >= 0) && msg->msg_name) { if ((rv >= 0) && msg->msg_name) {
__sockaddr_check_size(sizeof(struct sockaddr_dn));
memcpy(msg->msg_name, &scp->peer, sizeof(struct sockaddr_dn)); memcpy(msg->msg_name, &scp->peer, sizeof(struct sockaddr_dn));
msg->msg_namelen = sizeof(struct sockaddr_dn); msg->msg_namelen = sizeof(struct sockaddr_dn);
} }
@ -1914,7 +1915,7 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock,
int err = 0; int err = 0;
size_t sent = 0; size_t sent = 0;
int addr_len = msg->msg_namelen; int addr_len = msg->msg_namelen;
struct sockaddr_dn *addr = (struct sockaddr_dn *)msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_dn *, addr, msg->msg_name);
struct sk_buff *skb = NULL; struct sk_buff *skb = NULL;
struct dn_skb_cb *cb; struct dn_skb_cb *cb;
size_t len; size_t len;

View File

@ -291,9 +291,7 @@ static int dgram_recvmsg(struct kiocb *iocb, struct sock *sk,
size_t copied = 0; size_t copied = 0;
int err = -EOPNOTSUPP; int err = -EOPNOTSUPP;
struct sk_buff *skb; struct sk_buff *skb;
struct sockaddr_ieee802154 *saddr; DECLARE_SOCKADDR(struct sockaddr_ieee802154 *, saddr, msg->msg_name);
saddr = (struct sockaddr_ieee802154 *)msg->msg_name;
skb = skb_recv_datagram(sk, flags, noblock, &err); skb = skb_recv_datagram(sk, flags, noblock, &err);
if (!skb) if (!skb)

View File

@ -390,7 +390,7 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
{ {
struct sock_exterr_skb *serr; struct sock_exterr_skb *serr;
struct sk_buff *skb, *skb2; struct sk_buff *skb, *skb2;
struct sockaddr_in *sin; DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name);
struct { struct {
struct sock_extended_err ee; struct sock_extended_err ee;
struct sockaddr_in offender; struct sockaddr_in offender;
@ -416,7 +416,6 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
serr = SKB_EXT_ERR(skb); serr = SKB_EXT_ERR(skb);
sin = (struct sockaddr_in *)msg->msg_name;
if (sin) { if (sin) {
sin->sin_family = AF_INET; sin->sin_family = AF_INET;
sin->sin_addr.s_addr = *(__be32 *)(skb_network_header(skb) + sin->sin_addr.s_addr = *(__be32 *)(skb_network_header(skb) +

View File

@ -700,7 +700,7 @@ static int ping_v4_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m
*/ */
if (msg->msg_name) { if (msg->msg_name) {
struct sockaddr_in *usin = (struct sockaddr_in *)msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_in *, usin, msg->msg_name);
if (msg->msg_namelen < sizeof(*usin)) if (msg->msg_namelen < sizeof(*usin))
return -EINVAL; return -EINVAL;
if (usin->sin_family != AF_INET) if (usin->sin_family != AF_INET)
@ -873,7 +873,7 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
/* Copy the address and add cmsg data. */ /* Copy the address and add cmsg data. */
if (family == AF_INET) { if (family == AF_INET) {
struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name);
if (sin) { if (sin) {
sin->sin_family = AF_INET; sin->sin_family = AF_INET;
@ -890,8 +890,7 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
} else if (family == AF_INET6) { } else if (family == AF_INET6) {
struct ipv6_pinfo *np = inet6_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk);
struct ipv6hdr *ip6 = ipv6_hdr(skb); struct ipv6hdr *ip6 = ipv6_hdr(skb);
struct sockaddr_in6 *sin6 = DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name);
(struct sockaddr_in6 *)msg->msg_name;
if (sin6) { if (sin6) {
sin6->sin6_family = AF_INET6; sin6->sin6_family = AF_INET6;

View File

@ -493,7 +493,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
*/ */
if (msg->msg_namelen) { if (msg->msg_namelen) {
struct sockaddr_in *usin = (struct sockaddr_in *)msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_in *, usin, msg->msg_name);
err = -EINVAL; err = -EINVAL;
if (msg->msg_namelen < sizeof(*usin)) if (msg->msg_namelen < sizeof(*usin))
goto out; goto out;
@ -690,7 +690,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
struct inet_sock *inet = inet_sk(sk); struct inet_sock *inet = inet_sk(sk);
size_t copied = 0; size_t copied = 0;
int err = -EOPNOTSUPP; int err = -EOPNOTSUPP;
struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name);
struct sk_buff *skb; struct sk_buff *skb;
if (flags & MSG_OOB) if (flags & MSG_OOB)

View File

@ -902,7 +902,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
* Get and verify the address. * Get and verify the address.
*/ */
if (msg->msg_name) { if (msg->msg_name) {
struct sockaddr_in *usin = (struct sockaddr_in *)msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_in *, usin, msg->msg_name);
if (msg->msg_namelen < sizeof(*usin)) if (msg->msg_namelen < sizeof(*usin))
return -EINVAL; return -EINVAL;
if (usin->sin_family != AF_INET) { if (usin->sin_family != AF_INET) {
@ -1226,7 +1226,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
size_t len, int noblock, int flags, int *addr_len) size_t len, int noblock, int flags, int *addr_len)
{ {
struct inet_sock *inet = inet_sk(sk); struct inet_sock *inet = inet_sk(sk);
struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name);
struct sk_buff *skb; struct sk_buff *skb;
unsigned int ulen, copied; unsigned int ulen, copied;
int peeked, off = 0; int peeked, off = 0;

View File

@ -322,7 +322,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
struct ipv6_pinfo *np = inet6_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk);
struct sock_exterr_skb *serr; struct sock_exterr_skb *serr;
struct sk_buff *skb, *skb2; struct sk_buff *skb, *skb2;
struct sockaddr_in6 *sin; DECLARE_SOCKADDR(struct sockaddr_in6 *, sin, msg->msg_name);
struct { struct {
struct sock_extended_err ee; struct sock_extended_err ee;
struct sockaddr_in6 offender; struct sockaddr_in6 offender;
@ -348,7 +348,6 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
serr = SKB_EXT_ERR(skb); serr = SKB_EXT_ERR(skb);
sin = (struct sockaddr_in6 *)msg->msg_name;
if (sin) { if (sin) {
const unsigned char *nh = skb_network_header(skb); const unsigned char *nh = skb_network_header(skb);
sin->sin6_family = AF_INET6; sin->sin6_family = AF_INET6;
@ -429,8 +428,8 @@ int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len,
{ {
struct ipv6_pinfo *np = inet6_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk);
struct sk_buff *skb; struct sk_buff *skb;
struct sockaddr_in6 *sin;
struct ip6_mtuinfo mtu_info; struct ip6_mtuinfo mtu_info;
DECLARE_SOCKADDR(struct sockaddr_in6 *, sin, msg->msg_name);
int err; int err;
int copied; int copied;
@ -452,7 +451,6 @@ int ipv6_recv_rxpmtu(struct sock *sk, struct msghdr *msg, int len,
memcpy(&mtu_info, IP6CBMTU(skb), sizeof(mtu_info)); memcpy(&mtu_info, IP6CBMTU(skb), sizeof(mtu_info));
sin = (struct sockaddr_in6 *)msg->msg_name;
if (sin) { if (sin) {
sin->sin6_family = AF_INET6; sin->sin6_family = AF_INET6;
sin->sin6_flowinfo = 0; sin->sin6_flowinfo = 0;

View File

@ -103,7 +103,7 @@ int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
return err; return err;
if (msg->msg_name) { if (msg->msg_name) {
struct sockaddr_in6 *u = (struct sockaddr_in6 *) msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_in6 *, u, msg->msg_name);
if (msg->msg_namelen < sizeof(struct sockaddr_in6) || if (msg->msg_namelen < sizeof(struct sockaddr_in6) ||
u->sin6_family != AF_INET6) { u->sin6_family != AF_INET6) {
return -EINVAL; return -EINVAL;

View File

@ -457,7 +457,7 @@ static int rawv6_recvmsg(struct kiocb *iocb, struct sock *sk,
int noblock, int flags, int *addr_len) int noblock, int flags, int *addr_len)
{ {
struct ipv6_pinfo *np = inet6_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk);
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name);
struct sk_buff *skb; struct sk_buff *skb;
size_t copied; size_t copied;
int err; int err;
@ -734,7 +734,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
struct msghdr *msg, size_t len) struct msghdr *msg, size_t len)
{ {
struct ipv6_txoptions opt_space; struct ipv6_txoptions opt_space;
struct sockaddr_in6 * sin6 = (struct sockaddr_in6 *) msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name);
struct in6_addr *daddr, *final_p, final; struct in6_addr *daddr, *final_p, final;
struct inet_sock *inet = inet_sk(sk); struct inet_sock *inet = inet_sk(sk);
struct ipv6_pinfo *np = inet6_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk);

View File

@ -460,9 +460,7 @@ try_again:
/* Copy the address. */ /* Copy the address. */
if (msg->msg_name) { if (msg->msg_name) {
struct sockaddr_in6 *sin6; DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name);
sin6 = (struct sockaddr_in6 *) msg->msg_name;
sin6->sin6_family = AF_INET6; sin6->sin6_family = AF_INET6;
sin6->sin6_port = udp_hdr(skb)->source; sin6->sin6_port = udp_hdr(skb)->source;
sin6->sin6_flowinfo = 0; sin6->sin6_flowinfo = 0;
@ -1041,7 +1039,7 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
struct udp_sock *up = udp_sk(sk); struct udp_sock *up = udp_sk(sk);
struct inet_sock *inet = inet_sk(sk); struct inet_sock *inet = inet_sk(sk);
struct ipv6_pinfo *np = inet6_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk);
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name);
struct in6_addr *daddr, *final_p, final; struct in6_addr *daddr, *final_p, final;
struct ipv6_txoptions *opt = NULL; struct ipv6_txoptions *opt = NULL;
struct ip6_flowlabel *flowlabel = NULL; struct ip6_flowlabel *flowlabel = NULL;

View File

@ -1707,7 +1707,7 @@ static int ipx_sendmsg(struct kiocb *iocb, struct socket *sock,
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct ipx_sock *ipxs = ipx_sk(sk); struct ipx_sock *ipxs = ipx_sk(sk);
struct sockaddr_ipx *usipx = (struct sockaddr_ipx *)msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_ipx *, usipx, msg->msg_name);
struct sockaddr_ipx local_sipx; struct sockaddr_ipx local_sipx;
int rc = -EINVAL; int rc = -EINVAL;
int flags = msg->msg_flags; int flags = msg->msg_flags;
@ -1774,7 +1774,7 @@ static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct ipx_sock *ipxs = ipx_sk(sk); struct ipx_sock *ipxs = ipx_sk(sk);
struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_ipx *, sipx, msg->msg_name);
struct ipxhdr *ipx = NULL; struct ipxhdr *ipx = NULL;
struct sk_buff *skb; struct sk_buff *skb;
int copied, rc; int copied, rc;

View File

@ -1652,7 +1652,7 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock,
/* Check if an address was specified with sendto. Jean II */ /* Check if an address was specified with sendto. Jean II */
if (msg->msg_name) { if (msg->msg_name) {
struct sockaddr_irda *addr = (struct sockaddr_irda *) msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_irda *, addr, msg->msg_name);
err = -EINVAL; err = -EINVAL;
/* Check address, extract pid. Jean II */ /* Check address, extract pid. Jean II */
if (msg->msg_namelen < sizeof(*addr)) if (msg->msg_namelen < sizeof(*addr))

View File

@ -403,7 +403,7 @@ static int l2tp_ip_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m
/* Get and verify the address. */ /* Get and verify the address. */
if (msg->msg_name) { if (msg->msg_name) {
struct sockaddr_l2tpip *lip = (struct sockaddr_l2tpip *) msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_l2tpip *, lip, msg->msg_name);
rc = -EINVAL; rc = -EINVAL;
if (msg->msg_namelen < sizeof(*lip)) if (msg->msg_namelen < sizeof(*lip))
goto out; goto out;
@ -512,7 +512,7 @@ static int l2tp_ip_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m
struct inet_sock *inet = inet_sk(sk); struct inet_sock *inet = inet_sk(sk);
size_t copied = 0; size_t copied = 0;
int err = -EOPNOTSUPP; int err = -EOPNOTSUPP;
struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name);
struct sk_buff *skb; struct sk_buff *skb;
if (flags & MSG_OOB) if (flags & MSG_OOB)

View File

@ -481,8 +481,7 @@ static int l2tp_ip6_sendmsg(struct kiocb *iocb, struct sock *sk,
struct msghdr *msg, size_t len) struct msghdr *msg, size_t len)
{ {
struct ipv6_txoptions opt_space; struct ipv6_txoptions opt_space;
struct sockaddr_l2tpip6 *lsa = DECLARE_SOCKADDR(struct sockaddr_l2tpip6 *, lsa, msg->msg_name);
(struct sockaddr_l2tpip6 *) msg->msg_name;
struct in6_addr *daddr, *final_p, final; struct in6_addr *daddr, *final_p, final;
struct ipv6_pinfo *np = inet6_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk);
struct ipv6_txoptions *opt = NULL; struct ipv6_txoptions *opt = NULL;
@ -652,7 +651,7 @@ static int l2tp_ip6_recvmsg(struct kiocb *iocb, struct sock *sk,
int flags, int *addr_len) int flags, int *addr_len)
{ {
struct ipv6_pinfo *np = inet6_sk(sk); struct ipv6_pinfo *np = inet6_sk(sk);
struct sockaddr_l2tpip6 *lsa = (struct sockaddr_l2tpip6 *)msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_l2tpip6 *, lsa, msg->msg_name);
size_t copied = 0; size_t copied = 0;
int err = -EOPNOTSUPP; int err = -EOPNOTSUPP;
struct sk_buff *skb; struct sk_buff *skb;

View File

@ -707,7 +707,7 @@ out:
static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t len, int flags) struct msghdr *msg, size_t len, int flags)
{ {
struct sockaddr_llc *uaddr = (struct sockaddr_llc *)msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_llc *, uaddr, msg->msg_name);
const int nonblock = flags & MSG_DONTWAIT; const int nonblock = flags & MSG_DONTWAIT;
struct sk_buff *skb = NULL; struct sk_buff *skb = NULL;
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
@ -884,7 +884,7 @@ static int llc_ui_sendmsg(struct kiocb *iocb, struct socket *sock,
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct llc_sock *llc = llc_sk(sk); struct llc_sock *llc = llc_sk(sk);
struct sockaddr_llc *addr = (struct sockaddr_llc *)msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_llc *, addr, msg->msg_name);
int flags = msg->msg_flags; int flags = msg->msg_flags;
int noblock = flags & MSG_DONTWAIT; int noblock = flags & MSG_DONTWAIT;
struct sk_buff *skb; struct sk_buff *skb;

View File

@ -2222,7 +2222,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
struct sock_iocb *siocb = kiocb_to_siocb(kiocb); struct sock_iocb *siocb = kiocb_to_siocb(kiocb);
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct netlink_sock *nlk = nlk_sk(sk); struct netlink_sock *nlk = nlk_sk(sk);
struct sockaddr_nl *addr = msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_nl *, addr, msg->msg_name);
u32 dst_portid; u32 dst_portid;
u32 dst_group; u32 dst_group;
struct sk_buff *skb; struct sk_buff *skb;
@ -2353,7 +2353,7 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
err = skb_copy_datagram_iovec(data_skb, 0, msg->msg_iov, copied); err = skb_copy_datagram_iovec(data_skb, 0, msg->msg_iov, copied);
if (msg->msg_name) { if (msg->msg_name) {
struct sockaddr_nl *addr = (struct sockaddr_nl *)msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_nl *, addr, msg->msg_name);
addr->nl_family = AF_NETLINK; addr->nl_family = AF_NETLINK;
addr->nl_pad = 0; addr->nl_pad = 0;
addr->nl_pid = NETLINK_CB(skb).portid; addr->nl_pid = NETLINK_CB(skb).portid;

View File

@ -1028,7 +1028,7 @@ static int nr_sendmsg(struct kiocb *iocb, struct socket *sock,
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct nr_sock *nr = nr_sk(sk); struct nr_sock *nr = nr_sk(sk);
struct sockaddr_ax25 *usax = (struct sockaddr_ax25 *)msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_ax25 *, usax, msg->msg_name);
int err; int err;
struct sockaddr_ax25 sax; struct sockaddr_ax25 sax;
struct sk_buff *skb; struct sk_buff *skb;
@ -1137,7 +1137,7 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t size, int flags) struct msghdr *msg, size_t size, int flags)
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct sockaddr_ax25 *sax = (struct sockaddr_ax25 *)msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_ax25 *, sax, msg->msg_name);
size_t copied; size_t copied;
struct sk_buff *skb; struct sk_buff *skb;
int er; int er;

View File

@ -769,8 +769,8 @@ static int llcp_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
lock_sock(sk); lock_sock(sk);
if (sk->sk_type == SOCK_DGRAM) { if (sk->sk_type == SOCK_DGRAM) {
struct sockaddr_nfc_llcp *addr = DECLARE_SOCKADDR(struct sockaddr_nfc_llcp *, addr,
(struct sockaddr_nfc_llcp *)msg->msg_name; msg->msg_name);
if (msg->msg_namelen < sizeof(*addr)) { if (msg->msg_namelen < sizeof(*addr)) {
release_sock(sk); release_sock(sk);
@ -842,8 +842,8 @@ static int llcp_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
if (sk->sk_type == SOCK_DGRAM && msg->msg_name) { if (sk->sk_type == SOCK_DGRAM && msg->msg_name) {
struct nfc_llcp_ui_cb *ui_cb = nfc_llcp_ui_skb_cb(skb); struct nfc_llcp_ui_cb *ui_cb = nfc_llcp_ui_skb_cb(skb);
struct sockaddr_nfc_llcp *sockaddr = DECLARE_SOCKADDR(struct sockaddr_nfc_llcp *, sockaddr,
(struct sockaddr_nfc_llcp *) msg->msg_name; msg->msg_name);
msg->msg_namelen = sizeof(struct sockaddr_nfc_llcp); msg->msg_namelen = sizeof(struct sockaddr_nfc_llcp);

View File

@ -1584,7 +1584,7 @@ static int packet_sendmsg_spkt(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t len) struct msghdr *msg, size_t len)
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct sockaddr_pkt *saddr = (struct sockaddr_pkt *)msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_pkt *, saddr, msg->msg_name);
struct sk_buff *skb = NULL; struct sk_buff *skb = NULL;
struct net_device *dev; struct net_device *dev;
__be16 proto = 0; __be16 proto = 0;
@ -2196,7 +2196,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
__be16 proto; __be16 proto;
int err, reserve = 0; int err, reserve = 0;
void *ph; void *ph;
struct sockaddr_ll *saddr = (struct sockaddr_ll *)msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_ll *, saddr, msg->msg_name);
bool need_wait = !(msg->msg_flags & MSG_DONTWAIT); bool need_wait = !(msg->msg_flags & MSG_DONTWAIT);
int tp_len, size_max; int tp_len, size_max;
unsigned char *addr; unsigned char *addr;
@ -2346,7 +2346,7 @@ static struct sk_buff *packet_alloc_skb(struct sock *sk, size_t prepad,
static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct sockaddr_ll *saddr = (struct sockaddr_ll *)msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_ll *, saddr, msg->msg_name);
struct sk_buff *skb; struct sk_buff *skb;
struct net_device *dev; struct net_device *dev;
__be16 proto; __be16 proto;
@ -2922,6 +2922,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
* in, we fill it in now. * in, we fill it in now.
*/ */
if (sock->type == SOCK_PACKET) { if (sock->type == SOCK_PACKET) {
__sockaddr_check_size(sizeof(struct sockaddr_pkt));
msg->msg_namelen = sizeof(struct sockaddr_pkt); msg->msg_namelen = sizeof(struct sockaddr_pkt);
} else { } else {
struct sockaddr_ll *sll = &PACKET_SKB_CB(skb)->sa.ll; struct sockaddr_ll *sll = &PACKET_SKB_CB(skb)->sa.ll;

View File

@ -86,7 +86,7 @@ static int pn_init(struct sock *sk)
static int pn_sendmsg(struct kiocb *iocb, struct sock *sk, static int pn_sendmsg(struct kiocb *iocb, struct sock *sk,
struct msghdr *msg, size_t len) struct msghdr *msg, size_t len)
{ {
struct sockaddr_pn *target; DECLARE_SOCKADDR(struct sockaddr_pn *, target, msg->msg_name);
struct sk_buff *skb; struct sk_buff *skb;
int err; int err;
@ -94,13 +94,12 @@ static int pn_sendmsg(struct kiocb *iocb, struct sock *sk,
MSG_CMSG_COMPAT)) MSG_CMSG_COMPAT))
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (msg->msg_name == NULL) if (target == NULL)
return -EDESTADDRREQ; return -EDESTADDRREQ;
if (msg->msg_namelen < sizeof(struct sockaddr_pn)) if (msg->msg_namelen < sizeof(struct sockaddr_pn))
return -EINVAL; return -EINVAL;
target = (struct sockaddr_pn *)msg->msg_name;
if (target->spn_family != AF_PHONET) if (target->spn_family != AF_PHONET)
return -EAFNOSUPPORT; return -EAFNOSUPPORT;
@ -160,6 +159,7 @@ static int pn_recvmsg(struct kiocb *iocb, struct sock *sk,
rval = (flags & MSG_TRUNC) ? skb->len : copylen; rval = (flags & MSG_TRUNC) ? skb->len : copylen;
if (msg->msg_name != NULL) { if (msg->msg_name != NULL) {
__sockaddr_check_size(sizeof(sa));
memcpy(msg->msg_name, &sa, sizeof(sa)); memcpy(msg->msg_name, &sa, sizeof(sa));
*addr_len = sizeof(sa); *addr_len = sizeof(sa);
} }

View File

@ -402,7 +402,7 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
struct rds_sock *rs = rds_sk_to_rs(sk); struct rds_sock *rs = rds_sk_to_rs(sk);
long timeo; long timeo;
int ret = 0, nonblock = msg_flags & MSG_DONTWAIT; int ret = 0, nonblock = msg_flags & MSG_DONTWAIT;
struct sockaddr_in *sin; DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name);
struct rds_incoming *inc = NULL; struct rds_incoming *inc = NULL;
/* udp_recvmsg()->sock_recvtimeo() gets away without locking too.. */ /* udp_recvmsg()->sock_recvtimeo() gets away without locking too.. */
@ -479,7 +479,6 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
rds_stats_inc(s_recv_delivered); rds_stats_inc(s_recv_delivered);
sin = (struct sockaddr_in *)msg->msg_name;
if (sin) { if (sin) {
sin->sin_family = AF_INET; sin->sin_family = AF_INET;
sin->sin_port = inc->i_hdr.h_sport; sin->sin_port = inc->i_hdr.h_sport;

View File

@ -922,7 +922,7 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct rds_sock *rs = rds_sk_to_rs(sk); struct rds_sock *rs = rds_sk_to_rs(sk);
struct sockaddr_in *usin = (struct sockaddr_in *)msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_in *, usin, msg->msg_name);
__be32 daddr; __be32 daddr;
__be16 dport; __be16 dport;
struct rds_message *rm = NULL; struct rds_message *rm = NULL;

View File

@ -1051,7 +1051,7 @@ static int rose_sendmsg(struct kiocb *iocb, struct socket *sock,
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct rose_sock *rose = rose_sk(sk); struct rose_sock *rose = rose_sk(sk);
struct sockaddr_rose *usrose = (struct sockaddr_rose *)msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_rose *, usrose, msg->msg_name);
int err; int err;
struct full_sockaddr_rose srose; struct full_sockaddr_rose srose;
struct sk_buff *skb; struct sk_buff *skb;
@ -1253,7 +1253,8 @@ static int rose_recvmsg(struct kiocb *iocb, struct socket *sock,
if (msg->msg_name) { if (msg->msg_name) {
struct sockaddr_rose *srose; struct sockaddr_rose *srose;
struct full_sockaddr_rose *full_srose = msg->msg_name; DECLARE_SOCKADDR(struct full_sockaddr_rose *, full_srose,
msg->msg_name);
memset(msg->msg_name, 0, sizeof(struct full_sockaddr_rose)); memset(msg->msg_name, 0, sizeof(struct full_sockaddr_rose));
srose = msg->msg_name; srose = msg->msg_name;

View File

@ -152,8 +152,8 @@ int rxrpc_client_sendmsg(struct kiocb *iocb, struct rxrpc_sock *rx,
if (trans) { if (trans) {
service_id = rx->service_id; service_id = rx->service_id;
if (msg->msg_name) { if (msg->msg_name) {
struct sockaddr_rxrpc *srx = DECLARE_SOCKADDR(struct sockaddr_rxrpc *, srx,
(struct sockaddr_rxrpc *) msg->msg_name; msg->msg_name);
service_id = htons(srx->srx_service); service_id = htons(srx->srx_service);
} }
key = rx->key; key = rx->key;

View File

@ -608,7 +608,7 @@ static int send_msg(struct kiocb *iocb, struct socket *sock,
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct tipc_port *tport = tipc_sk_port(sk); struct tipc_port *tport = tipc_sk_port(sk);
struct sockaddr_tipc *dest = (struct sockaddr_tipc *)m->msg_name; DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name);
int needs_conn; int needs_conn;
long timeo; long timeo;
int res = -EINVAL; int res = -EINVAL;
@ -736,7 +736,7 @@ static int send_packet(struct kiocb *iocb, struct socket *sock,
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct tipc_port *tport = tipc_sk_port(sk); struct tipc_port *tport = tipc_sk_port(sk);
struct sockaddr_tipc *dest = (struct sockaddr_tipc *)m->msg_name; DECLARE_SOCKADDR(struct sockaddr_tipc *, dest, m->msg_name);
int res = -EINVAL; int res = -EINVAL;
long timeo; long timeo;
@ -906,7 +906,7 @@ static int auto_connect(struct socket *sock, struct tipc_msg *msg)
*/ */
static void set_orig_addr(struct msghdr *m, struct tipc_msg *msg) static void set_orig_addr(struct msghdr *m, struct tipc_msg *msg)
{ {
struct sockaddr_tipc *addr = (struct sockaddr_tipc *)m->msg_name; DECLARE_SOCKADDR(struct sockaddr_tipc *, addr, m->msg_name);
if (addr) { if (addr) {
addr->family = AF_TIPC; addr->family = AF_TIPC;

View File

@ -1450,7 +1450,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct net *net = sock_net(sk); struct net *net = sock_net(sk);
struct unix_sock *u = unix_sk(sk); struct unix_sock *u = unix_sk(sk);
struct sockaddr_un *sunaddr = msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, msg->msg_name);
struct sock *other = NULL; struct sock *other = NULL;
int namelen = 0; /* fake GCC */ int namelen = 0; /* fake GCC */
int err; int err;
@ -1912,7 +1912,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
struct scm_cookie tmp_scm; struct scm_cookie tmp_scm;
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct unix_sock *u = unix_sk(sk); struct unix_sock *u = unix_sk(sk);
struct sockaddr_un *sunaddr = msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_un *, sunaddr, msg->msg_name);
int copied = 0; int copied = 0;
int check_creds = 0; int check_creds = 0;
int target; int target;

View File

@ -1779,10 +1779,8 @@ static int vmci_transport_dgram_dequeue(struct kiocb *kiocb,
goto out; goto out;
if (msg->msg_name) { if (msg->msg_name) {
struct sockaddr_vm *vm_addr;
/* Provide the address of the sender. */ /* Provide the address of the sender. */
vm_addr = (struct sockaddr_vm *)msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_vm *, vm_addr, msg->msg_name);
vsock_addr_init(vm_addr, dg->src.context, dg->src.resource); vsock_addr_init(vm_addr, dg->src.context, dg->src.resource);
msg->msg_namelen = sizeof(*vm_addr); msg->msg_namelen = sizeof(*vm_addr);
} }

View File

@ -1082,7 +1082,7 @@ static int x25_sendmsg(struct kiocb *iocb, struct socket *sock,
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct x25_sock *x25 = x25_sk(sk); struct x25_sock *x25 = x25_sk(sk);
struct sockaddr_x25 *usx25 = (struct sockaddr_x25 *)msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_x25 *, usx25, msg->msg_name);
struct sockaddr_x25 sx25; struct sockaddr_x25 sx25;
struct sk_buff *skb; struct sk_buff *skb;
unsigned char *asmptr; unsigned char *asmptr;
@ -1258,7 +1258,7 @@ static int x25_recvmsg(struct kiocb *iocb, struct socket *sock,
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct x25_sock *x25 = x25_sk(sk); struct x25_sock *x25 = x25_sk(sk);
struct sockaddr_x25 *sx25 = (struct sockaddr_x25 *)msg->msg_name; DECLARE_SOCKADDR(struct sockaddr_x25 *, sx25, msg->msg_name);
size_t copied; size_t copied;
int qbit, header_len; int qbit, header_len;
struct sk_buff *skb; struct sk_buff *skb;