Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

inet: read sk->sk_family once in inet_recv_error()

inet_recv_error() is called without holding the socket lock.

IPv6 socket could mutate to IPv4 with IPV6_ADDRFORM
socket option and trigger a KCSAN warning.

Fixes: f4713a3dfad0 ("net-timestamp: make tcp_recvmsg call ipv6_recv_error for AF_INET6 socks")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Willem de Bruijn <willemb@google.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Eric Dumazet and committed by
David S. Miller
eef00a82 9cae43da

+4 -2
+4 -2
net/ipv4/af_inet.c
··· 1628 1628 1629 1629 int inet_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) 1630 1630 { 1631 - if (sk->sk_family == AF_INET) 1631 + unsigned int family = READ_ONCE(sk->sk_family); 1632 + 1633 + if (family == AF_INET) 1632 1634 return ip_recv_error(sk, msg, len, addr_len); 1633 1635 #if IS_ENABLED(CONFIG_IPV6) 1634 - if (sk->sk_family == AF_INET6) 1636 + if (family == AF_INET6) 1635 1637 return pingv6_ops.ipv6_recv_error(sk, msg, len, addr_len); 1636 1638 #endif 1637 1639 return -EINVAL;