Commit 0f95f7d4 authored by Martin KaFai Lau's avatar Martin KaFai Lau Committed by Alexei Starovoitov

bpf: net: Avoid do_ipv6_getsockopt() taking sk lock when called from bpf

Similar to the earlier patch that changes sk_getsockopt() to
use sockopt_{lock,release}_sock() such that it can avoid taking the
lock when called from bpf.  This patch also changes do_ipv6_getsockopt()
to use sockopt_{lock,release}_sock() such that bpf_getsockopt(SOL_IPV6)
can reuse do_ipv6_getsockopt().

Although bpf_getsockopt(SOL_IPV6) currently does not support optname
that requires lock_sock(), using sockopt_{lock,release}_sock()
consistently across *_getsockopt() will make future optname addition
harder to miss the sockopt_{lock,release}_sock() usage. eg. when
adding new optname that requires a lock and the new optname is
needed in bpf_getsockopt() also.
Signed-off-by: default avatarMartin KaFai Lau <martin.lau@kernel.org>
Link: https://lore.kernel.org/r/20220902002859.2893064-1-kafai@fb.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 6dadbe4b
...@@ -1078,7 +1078,7 @@ static int ipv6_get_msfilter(struct sock *sk, sockptr_t optval, ...@@ -1078,7 +1078,7 @@ static int ipv6_get_msfilter(struct sock *sk, sockptr_t optval,
if (gsf.gf_group.ss_family != AF_INET6) if (gsf.gf_group.ss_family != AF_INET6)
return -EADDRNOTAVAIL; return -EADDRNOTAVAIL;
num = gsf.gf_numsrc; num = gsf.gf_numsrc;
lock_sock(sk); sockopt_lock_sock(sk);
err = ip6_mc_msfget(sk, &gsf, optval, size0); err = ip6_mc_msfget(sk, &gsf, optval, size0);
if (!err) { if (!err) {
if (num > gsf.gf_numsrc) if (num > gsf.gf_numsrc)
...@@ -1088,7 +1088,7 @@ static int ipv6_get_msfilter(struct sock *sk, sockptr_t optval, ...@@ -1088,7 +1088,7 @@ static int ipv6_get_msfilter(struct sock *sk, sockptr_t optval,
copy_to_sockptr(optval, &gsf, size0)) copy_to_sockptr(optval, &gsf, size0))
err = -EFAULT; err = -EFAULT;
} }
release_sock(sk); sockopt_release_sock(sk);
return err; return err;
} }
...@@ -1114,9 +1114,9 @@ static int compat_ipv6_get_msfilter(struct sock *sk, sockptr_t optval, ...@@ -1114,9 +1114,9 @@ static int compat_ipv6_get_msfilter(struct sock *sk, sockptr_t optval,
if (gf.gf_group.ss_family != AF_INET6) if (gf.gf_group.ss_family != AF_INET6)
return -EADDRNOTAVAIL; return -EADDRNOTAVAIL;
lock_sock(sk); sockopt_lock_sock(sk);
err = ip6_mc_msfget(sk, &gf, optval, size0); err = ip6_mc_msfget(sk, &gf, optval, size0);
release_sock(sk); sockopt_release_sock(sk);
if (err) if (err)
return err; return err;
if (num > gf.gf_numsrc) if (num > gf.gf_numsrc)
...@@ -1175,11 +1175,11 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, ...@@ -1175,11 +1175,11 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
msg.msg_controllen = len; msg.msg_controllen = len;
msg.msg_flags = 0; msg.msg_flags = 0;
lock_sock(sk); sockopt_lock_sock(sk);
skb = np->pktoptions; skb = np->pktoptions;
if (skb) if (skb)
ip6_datagram_recv_ctl(sk, &msg, skb); ip6_datagram_recv_ctl(sk, &msg, skb);
release_sock(sk); sockopt_release_sock(sk);
if (!skb) { if (!skb) {
if (np->rxopt.bits.rxinfo) { if (np->rxopt.bits.rxinfo) {
struct in6_pktinfo src_info; struct in6_pktinfo src_info;
...@@ -1268,11 +1268,11 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, ...@@ -1268,11 +1268,11 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
{ {
struct ipv6_txoptions *opt; struct ipv6_txoptions *opt;
lock_sock(sk); sockopt_lock_sock(sk);
opt = rcu_dereference_protected(np->opt, opt = rcu_dereference_protected(np->opt,
lockdep_sock_is_held(sk)); lockdep_sock_is_held(sk));
len = ipv6_getsockopt_sticky(sk, opt, optname, optval, len); len = ipv6_getsockopt_sticky(sk, opt, optname, optval, len);
release_sock(sk); sockopt_release_sock(sk);
/* check if ipv6_getsockopt_sticky() returns err code */ /* check if ipv6_getsockopt_sticky() returns err code */
if (len < 0) if (len < 0)
return len; return len;
......
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