diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-02 14:03:34 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-02 14:03:34 -0400 |
commit | ea9866793d1e925b4d320eaea409263b2a568f38 (patch) | |
tree | 39b749b2c82febfcebb89706121d4f5781fffc1b /net/packet | |
parent | 5ce3307b6d9d25fe3c62e4749821f5e58f9161db (diff) | |
parent | 4dd2b82d5adfbe0b1587ccad7a8f76d826120f37 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller:
1) Out of bounds access in xfrm IPSEC policy unlink, from Yue Haibing.
2) Missing length check for esp4 UDP encap, from Sabrina Dubroca.
3) Fix byte order of RX STBC access in mac80211, from Johannes Berg.
4) Inifnite loop in bpftool map create, from Alban Crequy.
5) Register mark fix in ebpf verifier after pkt/null checks, from Paul
Chaignon.
6) Properly use rcu_dereference_sk_user_data in L2TP code, from Eric
Dumazet.
7) Buffer overrun in marvell phy driver, from Andrew Lunn.
8) Several crash and statistics handling fixes to bnxt_en driver, from
Michael Chan and Vasundhara Volam.
9) Several fixes to the TLS layer from Jakub Kicinski (copying negative
amounts of data in reencrypt, reencrypt frag copying, blind nskb->sk
NULL deref, etc).
10) Several UDP GRO fixes, from Paolo Abeni and Eric Dumazet.
11) PID/UID checks on ipv6 flow labels are inverted, from Willem de
Bruijn.
12) Use after free in l2tp, from Eric Dumazet.
13) IPV6 route destroy races, also from Eric Dumazet.
14) SCTP state machine can erroneously run recursively, fix from Xin
Long.
15) Adjust AF_PACKET msg_name length checks, add padding bytes if
necessary. From Willem de Bruijn.
16) Preserve skb_iif, so that forwarded packets have consistent values
even if fragmentation is involved. From Shmulik Ladkani.
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (69 commits)
udp: fix GRO packet of death
ipv6: A few fixes on dereferencing rt->from
rds: ib: force endiannes annotation
selftests: fib_rule_tests: print the result and return 1 if any tests failed
ipv4: ip_do_fragment: Preserve skb_iif during fragmentation
net/tls: avoid NULL pointer deref on nskb->sk in fallback
selftests: fib_rule_tests: Fix icmp proto with ipv6
packet: validate msg_namelen in send directly
packet: in recvmsg msg_name return at least sizeof sockaddr_ll
sctp: avoid running the sctp state machine recursively
stmmac: pci: Fix typo in IOT2000 comment
Documentation: fix netdev-FAQ.rst markup warning
ipv6: fix races in ip6_dst_destroy()
l2ip: fix possible use-after-free
appletalk: Set error code if register_snap_client failed
net: dsa: bcm_sf2: fix buffer overflow doing set_rxnfc
rxrpc: Fix net namespace cleanup
ipv6/flowlabel: wait rcu grace period before put_pid()
vrf: Use orig netdev to count Ip6InNoRoutes and a fresh route lookup when sending dest unreach
tcp: add sanity tests in tcp_add_backlog()
...
Diffstat (limited to 'net/packet')
-rw-r--r-- | net/packet/af_packet.c | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 9419c5cf4de5..9b81813dd16a 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -2602,8 +2602,8 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | |||
2602 | void *ph; | 2602 | void *ph; |
2603 | DECLARE_SOCKADDR(struct sockaddr_ll *, saddr, msg->msg_name); | 2603 | DECLARE_SOCKADDR(struct sockaddr_ll *, saddr, msg->msg_name); |
2604 | bool need_wait = !(msg->msg_flags & MSG_DONTWAIT); | 2604 | bool need_wait = !(msg->msg_flags & MSG_DONTWAIT); |
2605 | unsigned char *addr = NULL; | ||
2605 | int tp_len, size_max; | 2606 | int tp_len, size_max; |
2606 | unsigned char *addr; | ||
2607 | void *data; | 2607 | void *data; |
2608 | int len_sum = 0; | 2608 | int len_sum = 0; |
2609 | int status = TP_STATUS_AVAILABLE; | 2609 | int status = TP_STATUS_AVAILABLE; |
@@ -2614,7 +2614,6 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | |||
2614 | if (likely(saddr == NULL)) { | 2614 | if (likely(saddr == NULL)) { |
2615 | dev = packet_cached_dev_get(po); | 2615 | dev = packet_cached_dev_get(po); |
2616 | proto = po->num; | 2616 | proto = po->num; |
2617 | addr = NULL; | ||
2618 | } else { | 2617 | } else { |
2619 | err = -EINVAL; | 2618 | err = -EINVAL; |
2620 | if (msg->msg_namelen < sizeof(struct sockaddr_ll)) | 2619 | if (msg->msg_namelen < sizeof(struct sockaddr_ll)) |
@@ -2624,10 +2623,13 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | |||
2624 | sll_addr))) | 2623 | sll_addr))) |
2625 | goto out; | 2624 | goto out; |
2626 | proto = saddr->sll_protocol; | 2625 | proto = saddr->sll_protocol; |
2627 | addr = saddr->sll_halen ? saddr->sll_addr : NULL; | ||
2628 | dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex); | 2626 | dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex); |
2629 | if (addr && dev && saddr->sll_halen < dev->addr_len) | 2627 | if (po->sk.sk_socket->type == SOCK_DGRAM) { |
2630 | goto out_put; | 2628 | if (dev && msg->msg_namelen < dev->addr_len + |
2629 | offsetof(struct sockaddr_ll, sll_addr)) | ||
2630 | goto out_put; | ||
2631 | addr = saddr->sll_addr; | ||
2632 | } | ||
2631 | } | 2633 | } |
2632 | 2634 | ||
2633 | err = -ENXIO; | 2635 | err = -ENXIO; |
@@ -2799,7 +2801,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) | |||
2799 | struct sk_buff *skb; | 2801 | struct sk_buff *skb; |
2800 | struct net_device *dev; | 2802 | struct net_device *dev; |
2801 | __be16 proto; | 2803 | __be16 proto; |
2802 | unsigned char *addr; | 2804 | unsigned char *addr = NULL; |
2803 | int err, reserve = 0; | 2805 | int err, reserve = 0; |
2804 | struct sockcm_cookie sockc; | 2806 | struct sockcm_cookie sockc; |
2805 | struct virtio_net_hdr vnet_hdr = { 0 }; | 2807 | struct virtio_net_hdr vnet_hdr = { 0 }; |
@@ -2816,7 +2818,6 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) | |||
2816 | if (likely(saddr == NULL)) { | 2818 | if (likely(saddr == NULL)) { |
2817 | dev = packet_cached_dev_get(po); | 2819 | dev = packet_cached_dev_get(po); |
2818 | proto = po->num; | 2820 | proto = po->num; |
2819 | addr = NULL; | ||
2820 | } else { | 2821 | } else { |
2821 | err = -EINVAL; | 2822 | err = -EINVAL; |
2822 | if (msg->msg_namelen < sizeof(struct sockaddr_ll)) | 2823 | if (msg->msg_namelen < sizeof(struct sockaddr_ll)) |
@@ -2824,10 +2825,13 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) | |||
2824 | if (msg->msg_namelen < (saddr->sll_halen + offsetof(struct sockaddr_ll, sll_addr))) | 2825 | if (msg->msg_namelen < (saddr->sll_halen + offsetof(struct sockaddr_ll, sll_addr))) |
2825 | goto out; | 2826 | goto out; |
2826 | proto = saddr->sll_protocol; | 2827 | proto = saddr->sll_protocol; |
2827 | addr = saddr->sll_halen ? saddr->sll_addr : NULL; | ||
2828 | dev = dev_get_by_index(sock_net(sk), saddr->sll_ifindex); | 2828 | dev = dev_get_by_index(sock_net(sk), saddr->sll_ifindex); |
2829 | if (addr && dev && saddr->sll_halen < dev->addr_len) | 2829 | if (sock->type == SOCK_DGRAM) { |
2830 | goto out_unlock; | 2830 | if (dev && msg->msg_namelen < dev->addr_len + |
2831 | offsetof(struct sockaddr_ll, sll_addr)) | ||
2832 | goto out_unlock; | ||
2833 | addr = saddr->sll_addr; | ||
2834 | } | ||
2831 | } | 2835 | } |
2832 | 2836 | ||
2833 | err = -ENXIO; | 2837 | err = -ENXIO; |
@@ -3344,20 +3348,29 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, | |||
3344 | sock_recv_ts_and_drops(msg, sk, skb); | 3348 | sock_recv_ts_and_drops(msg, sk, skb); |
3345 | 3349 | ||
3346 | if (msg->msg_name) { | 3350 | if (msg->msg_name) { |
3351 | int copy_len; | ||
3352 | |||
3347 | /* If the address length field is there to be filled | 3353 | /* If the address length field is there to be filled |
3348 | * in, we fill it in now. | 3354 | * in, we fill it in now. |
3349 | */ | 3355 | */ |
3350 | if (sock->type == SOCK_PACKET) { | 3356 | if (sock->type == SOCK_PACKET) { |
3351 | __sockaddr_check_size(sizeof(struct sockaddr_pkt)); | 3357 | __sockaddr_check_size(sizeof(struct sockaddr_pkt)); |
3352 | msg->msg_namelen = sizeof(struct sockaddr_pkt); | 3358 | msg->msg_namelen = sizeof(struct sockaddr_pkt); |
3359 | copy_len = msg->msg_namelen; | ||
3353 | } else { | 3360 | } else { |
3354 | struct sockaddr_ll *sll = &PACKET_SKB_CB(skb)->sa.ll; | 3361 | struct sockaddr_ll *sll = &PACKET_SKB_CB(skb)->sa.ll; |
3355 | 3362 | ||
3356 | msg->msg_namelen = sll->sll_halen + | 3363 | msg->msg_namelen = sll->sll_halen + |
3357 | offsetof(struct sockaddr_ll, sll_addr); | 3364 | offsetof(struct sockaddr_ll, sll_addr); |
3365 | copy_len = msg->msg_namelen; | ||
3366 | if (msg->msg_namelen < sizeof(struct sockaddr_ll)) { | ||
3367 | memset(msg->msg_name + | ||
3368 | offsetof(struct sockaddr_ll, sll_addr), | ||
3369 | 0, sizeof(sll->sll_addr)); | ||
3370 | msg->msg_namelen = sizeof(struct sockaddr_ll); | ||
3371 | } | ||
3358 | } | 3372 | } |
3359 | memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa, | 3373 | memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa, copy_len); |
3360 | msg->msg_namelen); | ||
3361 | } | 3374 | } |
3362 | 3375 | ||
3363 | if (pkt_sk(sk)->auxdata) { | 3376 | if (pkt_sk(sk)->auxdata) { |