Commit e5fccaa1 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller

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: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent fdb5fd7f
...@@ -635,7 +635,9 @@ static int sock_bindtoindex_locked(struct sock *sk, int ifindex) ...@@ -635,7 +635,9 @@ static int sock_bindtoindex_locked(struct sock *sk, int ifindex)
if (ifindex < 0) if (ifindex < 0)
goto out; 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) if (sk->sk_prot->rehash)
sk->sk_prot->rehash(sk); sk->sk_prot->rehash(sk);
sk_dst_reset(sk); sk_dst_reset(sk);
...@@ -713,10 +715,11 @@ static int sock_getbindtodevice(struct sock *sk, char __user *optval, ...@@ -713,10 +715,11 @@ static int sock_getbindtodevice(struct sock *sk, char __user *optval,
{ {
int ret = -ENOPROTOOPT; int ret = -ENOPROTOOPT;
#ifdef CONFIG_NETDEVICES #ifdef CONFIG_NETDEVICES
int bound_dev_if = READ_ONCE(sk->sk_bound_dev_if);
struct net *net = sock_net(sk); struct net *net = sock_net(sk);
char devname[IFNAMSIZ]; char devname[IFNAMSIZ];
if (sk->sk_bound_dev_if == 0) { if (bound_dev_if == 0) {
len = 0; len = 0;
goto zero; goto zero;
} }
...@@ -725,7 +728,7 @@ static int sock_getbindtodevice(struct sock *sk, char __user *optval, ...@@ -725,7 +728,7 @@ static int sock_getbindtodevice(struct sock *sk, char __user *optval,
if (len < IFNAMSIZ) if (len < IFNAMSIZ)
goto out; goto out;
ret = netdev_get_name(net, devname, sk->sk_bound_dev_if); ret = netdev_get_name(net, devname, bound_dev_if);
if (ret) if (ret)
goto out; goto out;
...@@ -1861,7 +1864,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, ...@@ -1861,7 +1864,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
break; break;
case SO_BINDTOIFINDEX: case SO_BINDTOIFINDEX:
v.val = sk->sk_bound_dev_if; v.val = READ_ONCE(sk->sk_bound_dev_if);
break; break;
case SO_NETNS_COOKIE: case SO_NETNS_COOKIE:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment