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

l2tp: use add READ_ONCE() to fetch sk->sk_bound_dev_if

Use READ_ONCE() in paths not holding the socket lock.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Eric Dumazet and committed by
David S. Miller
ff009403 70f87de9

+8 -4
+3 -1
net/l2tp/l2tp_ip.c
··· 50 50 sk_for_each_bound(sk, &l2tp_ip_bind_table) { 51 51 const struct l2tp_ip_sock *l2tp = l2tp_ip_sk(sk); 52 52 const struct inet_sock *inet = inet_sk(sk); 53 + int bound_dev_if; 53 54 54 55 if (!net_eq(sock_net(sk), net)) 55 56 continue; 56 57 57 - if (sk->sk_bound_dev_if && dif && sk->sk_bound_dev_if != dif) 58 + bound_dev_if = READ_ONCE(sk->sk_bound_dev_if); 59 + if (bound_dev_if && dif && bound_dev_if != dif) 58 60 continue; 59 61 60 62 if (inet->inet_rcv_saddr && laddr &&
+5 -3
net/l2tp/l2tp_ip6.c
··· 62 62 const struct in6_addr *sk_laddr = inet6_rcv_saddr(sk); 63 63 const struct in6_addr *sk_raddr = &sk->sk_v6_daddr; 64 64 const struct l2tp_ip6_sock *l2tp = l2tp_ip6_sk(sk); 65 + int bound_dev_if; 65 66 66 67 if (!net_eq(sock_net(sk), net)) 67 68 continue; 68 69 69 - if (sk->sk_bound_dev_if && dif && sk->sk_bound_dev_if != dif) 70 + bound_dev_if = READ_ONCE(sk->sk_bound_dev_if); 71 + if (bound_dev_if && dif && bound_dev_if != dif) 70 72 continue; 71 73 72 74 if (sk_laddr && !ipv6_addr_any(sk_laddr) && ··· 447 445 lsa->l2tp_conn_id = lsk->conn_id; 448 446 } 449 447 if (ipv6_addr_type(&lsa->l2tp_addr) & IPV6_ADDR_LINKLOCAL) 450 - lsa->l2tp_scope_id = sk->sk_bound_dev_if; 448 + lsa->l2tp_scope_id = READ_ONCE(sk->sk_bound_dev_if); 451 449 return sizeof(*lsa); 452 450 } 453 451 ··· 562 560 } 563 561 564 562 if (fl6.flowi6_oif == 0) 565 - fl6.flowi6_oif = sk->sk_bound_dev_if; 563 + fl6.flowi6_oif = READ_ONCE(sk->sk_bound_dev_if); 566 564 567 565 if (msg->msg_controllen) { 568 566 opt = &opt_space;