diff options
| author | Steffen Hurrle <steffen@hurrle.net> | 2014-01-17 16:53:15 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2014-01-19 02:04:16 -0500 |
| commit | 342dfc306fb32155314dad277f3c3686b83fb9f1 (patch) | |
| tree | a0d220f9310725c72bac70945261c9282e7cf305 /net/ipv4 | |
| parent | ea02f9411d9faa3553ed09ce0ec9f00ceae9885e (diff) | |
net: add build-time checks for msg->msg_name size
This is a follow-up patch to f3d3342602f8bc ("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>
Diffstat (limited to 'net/ipv4')
| -rw-r--r-- | net/ipv4/ip_sockglue.c | 3 | ||||
| -rw-r--r-- | net/ipv4/ping.c | 7 | ||||
| -rw-r--r-- | net/ipv4/raw.c | 4 | ||||
| -rw-r--r-- | net/ipv4/udp.c | 4 |
4 files changed, 8 insertions, 10 deletions
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index a9fc435dc89f..22f15eb1c260 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
| @@ -390,7 +390,7 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) | |||
| 390 | { | 390 | { |
| 391 | struct sock_exterr_skb *serr; | 391 | struct sock_exterr_skb *serr; |
| 392 | struct sk_buff *skb, *skb2; | 392 | struct sk_buff *skb, *skb2; |
| 393 | struct sockaddr_in *sin; | 393 | DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name); |
| 394 | struct { | 394 | struct { |
| 395 | struct sock_extended_err ee; | 395 | struct sock_extended_err ee; |
| 396 | struct sockaddr_in offender; | 396 | struct sockaddr_in offender; |
| @@ -416,7 +416,6 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) | |||
| 416 | 416 | ||
| 417 | serr = SKB_EXT_ERR(skb); | 417 | serr = SKB_EXT_ERR(skb); |
| 418 | 418 | ||
| 419 | sin = (struct sockaddr_in *)msg->msg_name; | ||
| 420 | if (sin) { | 419 | if (sin) { |
| 421 | sin->sin_family = AF_INET; | 420 | sin->sin_family = AF_INET; |
| 422 | sin->sin_addr.s_addr = *(__be32 *)(skb_network_header(skb) + | 421 | sin->sin_addr.s_addr = *(__be32 *)(skb_network_header(skb) + |
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index cae5262a337c..e09e8839d622 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c | |||
| @@ -700,7 +700,7 @@ static int ping_v4_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m | |||
| 700 | */ | 700 | */ |
| 701 | 701 | ||
| 702 | if (msg->msg_name) { | 702 | if (msg->msg_name) { |
| 703 | struct sockaddr_in *usin = (struct sockaddr_in *)msg->msg_name; | 703 | DECLARE_SOCKADDR(struct sockaddr_in *, usin, msg->msg_name); |
| 704 | if (msg->msg_namelen < sizeof(*usin)) | 704 | if (msg->msg_namelen < sizeof(*usin)) |
| 705 | return -EINVAL; | 705 | return -EINVAL; |
| 706 | if (usin->sin_family != AF_INET) | 706 | if (usin->sin_family != AF_INET) |
| @@ -873,7 +873,7 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 873 | 873 | ||
| 874 | /* Copy the address and add cmsg data. */ | 874 | /* Copy the address and add cmsg data. */ |
| 875 | if (family == AF_INET) { | 875 | if (family == AF_INET) { |
| 876 | struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name; | 876 | DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name); |
| 877 | 877 | ||
| 878 | if (sin) { | 878 | if (sin) { |
| 879 | sin->sin_family = AF_INET; | 879 | sin->sin_family = AF_INET; |
| @@ -890,8 +890,7 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 890 | } else if (family == AF_INET6) { | 890 | } else if (family == AF_INET6) { |
| 891 | struct ipv6_pinfo *np = inet6_sk(sk); | 891 | struct ipv6_pinfo *np = inet6_sk(sk); |
| 892 | struct ipv6hdr *ip6 = ipv6_hdr(skb); | 892 | struct ipv6hdr *ip6 = ipv6_hdr(skb); |
| 893 | struct sockaddr_in6 *sin6 = | 893 | DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name); |
| 894 | (struct sockaddr_in6 *)msg->msg_name; | ||
| 895 | 894 | ||
| 896 | if (sin6) { | 895 | if (sin6) { |
| 897 | sin6->sin6_family = AF_INET6; | 896 | sin6->sin6_family = AF_INET6; |
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 81e6cfd5a365..c04518f4850a 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
| @@ -493,7 +493,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 493 | */ | 493 | */ |
| 494 | 494 | ||
| 495 | if (msg->msg_namelen) { | 495 | if (msg->msg_namelen) { |
| 496 | struct sockaddr_in *usin = (struct sockaddr_in *)msg->msg_name; | 496 | DECLARE_SOCKADDR(struct sockaddr_in *, usin, msg->msg_name); |
| 497 | err = -EINVAL; | 497 | err = -EINVAL; |
| 498 | if (msg->msg_namelen < sizeof(*usin)) | 498 | if (msg->msg_namelen < sizeof(*usin)) |
| 499 | goto out; | 499 | goto out; |
| @@ -690,7 +690,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 690 | struct inet_sock *inet = inet_sk(sk); | 690 | struct inet_sock *inet = inet_sk(sk); |
| 691 | size_t copied = 0; | 691 | size_t copied = 0; |
| 692 | int err = -EOPNOTSUPP; | 692 | int err = -EOPNOTSUPP; |
| 693 | struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name; | 693 | DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name); |
| 694 | struct sk_buff *skb; | 694 | struct sk_buff *skb; |
| 695 | 695 | ||
| 696 | if (flags & MSG_OOB) | 696 | if (flags & MSG_OOB) |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 3d3141fd0580..77bd16fa9f34 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
| @@ -902,7 +902,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 902 | * Get and verify the address. | 902 | * Get and verify the address. |
| 903 | */ | 903 | */ |
| 904 | if (msg->msg_name) { | 904 | if (msg->msg_name) { |
| 905 | struct sockaddr_in *usin = (struct sockaddr_in *)msg->msg_name; | 905 | DECLARE_SOCKADDR(struct sockaddr_in *, usin, msg->msg_name); |
| 906 | if (msg->msg_namelen < sizeof(*usin)) | 906 | if (msg->msg_namelen < sizeof(*usin)) |
| 907 | return -EINVAL; | 907 | return -EINVAL; |
| 908 | if (usin->sin_family != AF_INET) { | 908 | if (usin->sin_family != AF_INET) { |
| @@ -1226,7 +1226,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 1226 | size_t len, int noblock, int flags, int *addr_len) | 1226 | size_t len, int noblock, int flags, int *addr_len) |
| 1227 | { | 1227 | { |
| 1228 | struct inet_sock *inet = inet_sk(sk); | 1228 | struct inet_sock *inet = inet_sk(sk); |
| 1229 | struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name; | 1229 | DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name); |
| 1230 | struct sk_buff *skb; | 1230 | struct sk_buff *skb; |
| 1231 | unsigned int ulen, copied; | 1231 | unsigned int ulen, copied; |
| 1232 | int peeked, off = 0; | 1232 | int peeked, off = 0; |
