aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/packet/af_packet.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 9419c5cf4de5..7d361cd53ad5 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -3344,20 +3344,29 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
3344 sock_recv_ts_and_drops(msg, sk, skb); 3344 sock_recv_ts_and_drops(msg, sk, skb);
3345 3345
3346 if (msg->msg_name) { 3346 if (msg->msg_name) {
3347 int copy_len;
3348
3347 /* If the address length field is there to be filled 3349 /* If the address length field is there to be filled
3348 * in, we fill it in now. 3350 * in, we fill it in now.
3349 */ 3351 */
3350 if (sock->type == SOCK_PACKET) { 3352 if (sock->type == SOCK_PACKET) {
3351 __sockaddr_check_size(sizeof(struct sockaddr_pkt)); 3353 __sockaddr_check_size(sizeof(struct sockaddr_pkt));
3352 msg->msg_namelen = sizeof(struct sockaddr_pkt); 3354 msg->msg_namelen = sizeof(struct sockaddr_pkt);
3355 copy_len = msg->msg_namelen;
3353 } else { 3356 } else {
3354 struct sockaddr_ll *sll = &PACKET_SKB_CB(skb)->sa.ll; 3357 struct sockaddr_ll *sll = &PACKET_SKB_CB(skb)->sa.ll;
3355 3358
3356 msg->msg_namelen = sll->sll_halen + 3359 msg->msg_namelen = sll->sll_halen +
3357 offsetof(struct sockaddr_ll, sll_addr); 3360 offsetof(struct sockaddr_ll, sll_addr);
3361 copy_len = msg->msg_namelen;
3362 if (msg->msg_namelen < sizeof(struct sockaddr_ll)) {
3363 memset(msg->msg_name +
3364 offsetof(struct sockaddr_ll, sll_addr),
3365 0, sizeof(sll->sll_addr));
3366 msg->msg_namelen = sizeof(struct sockaddr_ll);
3367 }
3358 } 3368 }
3359 memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa, 3369 memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa, copy_len);
3360 msg->msg_namelen);
3361 } 3370 }
3362 3371
3363 if (pkt_sk(sk)->auxdata) { 3372 if (pkt_sk(sk)->auxdata) {