From: Willem de Bruijn [mailto:willemdebruijn.ker...@gmail.com] > Sent: 26 April 2019 20:30 > Packet send checks that msg_name is at least sizeof sockaddr_ll. > Packet recv must return at least this length, so that its output > can be passed unmodified to packet send. > > This ceased to be true since adding support for lladdr longer than > sll_addr. Since, the return value uses true address length. > > Always return at least sizeof sockaddr_ll, even if address length > is shorter. Zero the padding bytes. > > Fixes: 0fb375fb9b93 ("[AF_PACKET]: Allow for > 8 byte hardware addresses.") > Suggested-by: David Laight <david.lai...@aculab.com> > Signed-off-by: Willem de Bruijn <will...@google.com> > --- > net/packet/af_packet.c | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > > diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c > index 13301e36b4a28..ca38e75c702e7 100644 > --- a/net/packet/af_packet.c > +++ b/net/packet/af_packet.c > @@ -3358,9 +3358,14 @@ static int packet_recvmsg(struct socket *sock, struct > msghdr *msg, size_t len, > msg->msg_namelen = sizeof(struct sockaddr_pkt); > } else { > struct sockaddr_ll *sll = &PACKET_SKB_CB(skb)->sa.ll; > - > msg->msg_namelen = sll->sll_halen + > offsetof(struct sockaddr_ll, sll_addr); > + if (msg->msg_namelen < sizeof(struct sockaddr_ll)) { > + memset(msg->msg_name + > + offsetof(struct sockaddr_ll, sll_addr), > + 0, sizeof(sll->sll_addr)); > + msg->msg_namelen = sizeof(struct sockaddr_ll); > + } > } > memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa, > msg->msg_namelen);
That memcpy() carefully overwrites the zeroed bytes. You need a separate 'copy_len' that isn't updated (from 18 to 20). David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)