aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/packet/af_packet.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 7d361cd53ad5..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;