提交 6c566167 编写于 作者: W Willem de Bruijn 提交者: Xie XiuQi

packet: in recvmsg msg_name return at least sizeof sockaddr_ll

mainline inclusion
from mainline-5.1
commit b2cf86e1563e
category: bugfix
bugzilla: 14326
CVE: NA

-------------------------------------------------

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.

Change v1->v2: do not overwrite zeroed padding again. use copy_len.

Fixes: 0fb375fb ("[AF_PACKET]: Allow for > 8 byte hardware addresses.")
Suggested-by: NDavid Laight <David.Laight@aculab.com>
Signed-off-by: NWillem de Bruijn <willemb@google.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
Signed-off-by: NZhiqiang Liu <liuzhiqiang26@huawei.com>
Reviewed-by: NWenan Mao <maowenan@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 60177a55
...@@ -3349,20 +3349,29 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, ...@@ -3349,20 +3349,29 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
sock_recv_ts_and_drops(msg, sk, skb); sock_recv_ts_and_drops(msg, sk, skb);
if (msg->msg_name) { if (msg->msg_name) {
int copy_len;
/* If the address length field is there to be filled /* If the address length field is there to be filled
* in, we fill it in now. * in, we fill it in now.
*/ */
if (sock->type == SOCK_PACKET) { if (sock->type == SOCK_PACKET) {
__sockaddr_check_size(sizeof(struct sockaddr_pkt)); __sockaddr_check_size(sizeof(struct sockaddr_pkt));
msg->msg_namelen = sizeof(struct sockaddr_pkt); msg->msg_namelen = sizeof(struct sockaddr_pkt);
copy_len = msg->msg_namelen;
} else { } else {
struct sockaddr_ll *sll = &PACKET_SKB_CB(skb)->sa.ll; struct sockaddr_ll *sll = &PACKET_SKB_CB(skb)->sa.ll;
msg->msg_namelen = sll->sll_halen + msg->msg_namelen = sll->sll_halen +
offsetof(struct sockaddr_ll, sll_addr); offsetof(struct sockaddr_ll, sll_addr);
copy_len = msg->msg_namelen;
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, memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa, copy_len);
msg->msg_namelen);
} }
if (pkt_sk(sk)->auxdata) { if (pkt_sk(sk)->auxdata) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册