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

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

Similar to the earlier commit that changed sk_setsockopt() to
use sockopt_{lock,release}_sock() such that it can avoid taking
lock when called from bpf.  This patch also changes do_tcp_getsockopt()
to use sockopt_{lock,release}_sock() such that a latter patch can
make bpf_getsockopt(SOL_TCP) to reuse do_tcp_getsockopt().
Signed-off-by: default avatarMartin KaFai Lau <martin.lau@kernel.org>
Link: https://lore.kernel.org/r/20220902002821.2889765-1-kafai@fb.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 34704ef0
...@@ -4265,30 +4265,30 @@ static int do_tcp_getsockopt(struct sock *sk, int level, ...@@ -4265,30 +4265,30 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
if (copy_from_sockptr(&len, optlen, sizeof(int))) if (copy_from_sockptr(&len, optlen, sizeof(int)))
return -EFAULT; return -EFAULT;
lock_sock(sk); sockopt_lock_sock(sk);
if (tp->saved_syn) { if (tp->saved_syn) {
if (len < tcp_saved_syn_len(tp->saved_syn)) { if (len < tcp_saved_syn_len(tp->saved_syn)) {
len = tcp_saved_syn_len(tp->saved_syn); len = tcp_saved_syn_len(tp->saved_syn);
if (copy_to_sockptr(optlen, &len, sizeof(int))) { if (copy_to_sockptr(optlen, &len, sizeof(int))) {
release_sock(sk); sockopt_release_sock(sk);
return -EFAULT; return -EFAULT;
} }
release_sock(sk); sockopt_release_sock(sk);
return -EINVAL; return -EINVAL;
} }
len = tcp_saved_syn_len(tp->saved_syn); len = tcp_saved_syn_len(tp->saved_syn);
if (copy_to_sockptr(optlen, &len, sizeof(int))) { if (copy_to_sockptr(optlen, &len, sizeof(int))) {
release_sock(sk); sockopt_release_sock(sk);
return -EFAULT; return -EFAULT;
} }
if (copy_to_sockptr(optval, tp->saved_syn->data, len)) { if (copy_to_sockptr(optval, tp->saved_syn->data, len)) {
release_sock(sk); sockopt_release_sock(sk);
return -EFAULT; return -EFAULT;
} }
tcp_saved_syn_free(tp); tcp_saved_syn_free(tp);
release_sock(sk); sockopt_release_sock(sk);
} else { } else {
release_sock(sk); sockopt_release_sock(sk);
len = 0; len = 0;
if (copy_to_sockptr(optlen, &len, sizeof(int))) if (copy_to_sockptr(optlen, &len, sizeof(int)))
return -EFAULT; return -EFAULT;
...@@ -4321,11 +4321,11 @@ static int do_tcp_getsockopt(struct sock *sk, int level, ...@@ -4321,11 +4321,11 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
return -EINVAL; return -EINVAL;
if (zc.msg_flags & ~(TCP_VALID_ZC_MSG_FLAGS)) if (zc.msg_flags & ~(TCP_VALID_ZC_MSG_FLAGS))
return -EINVAL; return -EINVAL;
lock_sock(sk); sockopt_lock_sock(sk);
err = tcp_zerocopy_receive(sk, &zc, &tss); err = tcp_zerocopy_receive(sk, &zc, &tss);
err = BPF_CGROUP_RUN_PROG_GETSOCKOPT_KERN(sk, level, optname, err = BPF_CGROUP_RUN_PROG_GETSOCKOPT_KERN(sk, level, optname,
&zc, &len, err); &zc, &len, err);
release_sock(sk); sockopt_release_sock(sk);
if (len >= offsetofend(struct tcp_zerocopy_receive, msg_flags)) if (len >= offsetofend(struct tcp_zerocopy_receive, msg_flags))
goto zerocopy_rcv_cmsg; goto zerocopy_rcv_cmsg;
switch (len) { switch (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