@@ -2616,6 +2616,9 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
proto = po->num;
addr = NULL;
} else {
+ const int sa_len = offsetof(struct sockaddr_ll, sll_addr);
+ const short sk_type = po->sk.sk_socket->type;
+
err = -EINVAL;
if (msg->msg_namelen < sizeof(struct sockaddr_ll))
goto out;
@@ -2624,9 +2627,9 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
sll_addr)))
goto out;
proto = saddr->sll_protocol;
- addr = saddr->sll_halen ? saddr->sll_addr : NULL;
+ addr = sk_type == SOCK_DGRAM ? saddr->sll_addr : NULL;
dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex);
- if (addr && dev && saddr->sll_halen < dev->addr_len)
+ if (addr && dev && msg->msg_namelen < (sa_len + dev->addr_len))
goto out_put;
}
@@ -2818,15 +2821,17 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len)
proto = po->num;
addr = NULL;
} else {
+ const int sa_len = offsetof(struct sockaddr_ll, sll_addr);
+
err = -EINVAL;
if (msg->msg_namelen < sizeof(struct sockaddr_ll))
goto out;
if (msg->msg_namelen < (saddr->sll_halen + offsetof(struct sockaddr_ll, sll_addr)))
goto out;
proto = saddr->sll_protocol;
- addr = saddr->sll_halen ? saddr->sll_addr : NULL;
+ addr = sock->type == SOCK_DGRAM ? saddr->sll_addr : NULL;
dev = dev_get_by_index(sock_net(sk), saddr->sll_ifindex);
- if (addr && dev && saddr->sll_halen < dev->addr_len)
+ if (addr && dev && msg->msg_namelen < (sa_len + dev->addr_len))
goto out_unlock;
}