mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 13:14:07 +08:00
net: core: add READ_ONCE/WRITE_ONCE annotations for sk->sk_bound_dev_if
sock_bindtoindex_locked() needs to use WRITE_ONCE(sk->sk_bound_dev_if, val), because other cpus/threads might locklessly read this field. sock_getbindtodevice(), sock_getsockopt() need READ_ONCE() because they run without socket lock held. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
fdb5fd7f73
commit
e5fccaa1eb
@ -635,7 +635,9 @@ static int sock_bindtoindex_locked(struct sock *sk, int ifindex)
|
||||
if (ifindex < 0)
|
||||
goto out;
|
||||
|
||||
sk->sk_bound_dev_if = ifindex;
|
||||
/* Paired with all READ_ONCE() done locklessly. */
|
||||
WRITE_ONCE(sk->sk_bound_dev_if, ifindex);
|
||||
|
||||
if (sk->sk_prot->rehash)
|
||||
sk->sk_prot->rehash(sk);
|
||||
sk_dst_reset(sk);
|
||||
@ -713,10 +715,11 @@ static int sock_getbindtodevice(struct sock *sk, char __user *optval,
|
||||
{
|
||||
int ret = -ENOPROTOOPT;
|
||||
#ifdef CONFIG_NETDEVICES
|
||||
int bound_dev_if = READ_ONCE(sk->sk_bound_dev_if);
|
||||
struct net *net = sock_net(sk);
|
||||
char devname[IFNAMSIZ];
|
||||
|
||||
if (sk->sk_bound_dev_if == 0) {
|
||||
if (bound_dev_if == 0) {
|
||||
len = 0;
|
||||
goto zero;
|
||||
}
|
||||
@ -725,7 +728,7 @@ static int sock_getbindtodevice(struct sock *sk, char __user *optval,
|
||||
if (len < IFNAMSIZ)
|
||||
goto out;
|
||||
|
||||
ret = netdev_get_name(net, devname, sk->sk_bound_dev_if);
|
||||
ret = netdev_get_name(net, devname, bound_dev_if);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
@ -1861,7 +1864,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
|
||||
break;
|
||||
|
||||
case SO_BINDTOIFINDEX:
|
||||
v.val = sk->sk_bound_dev_if;
|
||||
v.val = READ_ONCE(sk->sk_bound_dev_if);
|
||||
break;
|
||||
|
||||
case SO_NETNS_COOKIE:
|
||||
|
Loading…
Reference in New Issue
Block a user