Use READ_ONCE() in paths not holding the socket lock.
Unified · Split
| @@ -50,11 +50,13 @@ static struct sock *__l2tp_ip_bind_lookup(const struct net *net, __be32 laddr, · 49 unmodified lines | ||
| 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 && |
| @@ -62,11 +62,13 @@ static struct sock *__l2tp_ip6_bind_lookup(const struct net *net, · 61 unmodified lines | ||
| 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) && |
| @@ -445,7 +447,7 @@ static int l2tp_ip6_getname(struct socket *sock, struct sockaddr *uaddr, · 372 unmodified lines | ||
| 445 | 447 | lsa->l2tp_conn_id = lsk->conn_id; |
| 446 | 448 | } |
| 447 | 449 | if (ipv6_addr_type(&lsa->l2tp_addr) & IPV6_ADDR_LINKLOCAL) |
| 448 | − lsa->l2tp_scope_id = sk->sk_bound_dev_if; | |
| 450 | + lsa->l2tp_scope_id = READ_ONCE(sk->sk_bound_dev_if); | |
| 449 | 451 | return sizeof(*lsa); |
| 450 | 452 | } |
| 451 | 453 | |
| @@ -560,7 +562,7 @@ static int l2tp_ip6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) · 108 unmodified lines | ||
| 560 | 562 | } |
| 561 | 563 | |
| 562 | 564 | if (fl6.flowi6_oif == 0) |
| 563 | − fl6.flowi6_oif = sk->sk_bound_dev_if; | |
| 565 | + fl6.flowi6_oif = READ_ONCE(sk->sk_bound_dev_if); | |
| 564 | 566 | |
| 565 | 567 | if (msg->msg_controllen) { |
| 566 | 568 | opt = &opt_space; |