af_packet: avoid a false positive warning in packet_setsockopt()
[ Upstream commit 86d43e2bf93ccac88ef71cee36a23282ebd9e427 ] Although the code is correct, the following line copy_from_sockptr(&req_u.req, optval, len)); triggers this warning : memcpy: detected field-spanning write (size 28) of single field "dst" at include/linux/sockptr.h:49 (size 16) Refactor the code to be more explicit. Reported-by: syzbot <syzkaller@googlegroups.com> Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Kees Cook <keescook@chromium.org> Cc: Willem de Bruijn <willemdebruijn.kernel@gmail.com> Reviewed-by: Kees Cook <keescook@chromium.org> Reviewed-by: Willem de Bruijn <willemb@google.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
b5a53d14dd
commit
a720d71dd4
@@ -3761,28 +3761,30 @@ packet_setsockopt(struct socket *sock, int level, int optname, sockptr_t optval,
|
|||||||
case PACKET_TX_RING:
|
case PACKET_TX_RING:
|
||||||
{
|
{
|
||||||
union tpacket_req_u req_u;
|
union tpacket_req_u req_u;
|
||||||
int len;
|
|
||||||
|
|
||||||
|
ret = -EINVAL;
|
||||||
lock_sock(sk);
|
lock_sock(sk);
|
||||||
switch (po->tp_version) {
|
switch (po->tp_version) {
|
||||||
case TPACKET_V1:
|
case TPACKET_V1:
|
||||||
case TPACKET_V2:
|
case TPACKET_V2:
|
||||||
len = sizeof(req_u.req);
|
if (optlen < sizeof(req_u.req))
|
||||||
|
break;
|
||||||
|
ret = copy_from_sockptr(&req_u.req, optval,
|
||||||
|
sizeof(req_u.req)) ?
|
||||||
|
-EINVAL : 0;
|
||||||
break;
|
break;
|
||||||
case TPACKET_V3:
|
case TPACKET_V3:
|
||||||
default:
|
default:
|
||||||
len = sizeof(req_u.req3);
|
if (optlen < sizeof(req_u.req3))
|
||||||
|
break;
|
||||||
|
ret = copy_from_sockptr(&req_u.req3, optval,
|
||||||
|
sizeof(req_u.req3)) ?
|
||||||
|
-EINVAL : 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (optlen < len) {
|
if (!ret)
|
||||||
ret = -EINVAL;
|
ret = packet_set_ring(sk, &req_u, 0,
|
||||||
} else {
|
optname == PACKET_TX_RING);
|
||||||
if (copy_from_sockptr(&req_u.req, optval, len))
|
|
||||||
ret = -EFAULT;
|
|
||||||
else
|
|
||||||
ret = packet_set_ring(sk, &req_u, 0,
|
|
||||||
optname == PACKET_TX_RING);
|
|
||||||
}
|
|
||||||
release_sock(sk);
|
release_sock(sk);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user