[PATCH mptcp-next v3 4/7] mptcp: reject sockopt requiring ssks' lock in BPF context
Gang Yan <[email protected]> Mon, 27 Jul 2026 10:28:46 +0800
| Newsgroups | dev.linux.lists.mptcp |
|---|---|
| Message-ID | <[email protected]> |
From: Gang Yan <[email protected]> Several MPTCP setsockopt handlers need to acquire the subflow lock via lock_sock(ssk) to propagate settings to each subflow. This lock can sleep and is therefore not usable in BPF context where sleeping is forbidden. The short-term solution is to make any sockopt operation that requires subflow-level lock fail with -EOPNOTSUPP when called from BPF context. Signed-off-by: Gang Yan <[email protected]> --- net/mptcp/sockopt.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c index f00d85809c52..a26758a82150 100644 --- a/net/mptcp/sockopt.c +++ b/net/mptcp/sockopt.c @@ -185,6 +185,9 @@ static int mptcp_setsockopt_sol_socket_int(struct mptcp_sock *msk, int optname, if (ret) return ret; + if (has_current_bpf_ctx()) + return -EOPNOTSUPP; + switch (optname) { case SO_KEEPALIVE: case SO_DEBUG: @@ -218,6 +221,9 @@ static int mptcp_setsockopt_sol_socket_timestamping(struct mptcp_sock *msk, struct so_timestamping timestamping; int ret; + if (has_current_bpf_ctx()) + return -EOPNOTSUPP; + if (optlen == sizeof(timestamping)) { if (copy_from_sockptr(×tamping, optval, sizeof(timestamping))) @@ -265,6 +271,9 @@ static int mptcp_setsockopt_sol_socket_linger(struct mptcp_sock *msk, sockptr_t sockptr_t kopt; int ret; + if (has_current_bpf_ctx()) + return -EOPNOTSUPP; + if (optlen < sizeof(ling)) return -EINVAL; @@ -598,6 +607,9 @@ static int mptcp_setsockopt_sol_tcp_congestion(struct mptcp_sock *msk, sockptr_t bool cap_net_admin; int ret; + if (has_current_bpf_ctx()) + return -EOPNOTSUPP; + if (optlen < 1) return -EINVAL; @@ -639,6 +651,9 @@ static int __mptcp_setsockopt_set_val(struct mptcp_sock *msk, struct mptcp_subflow_context *subflow; int err = 0; + if (has_current_bpf_ctx()) + return -EOPNOTSUPP; + mptcp_for_each_subflow(msk, subflow) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow); int ret; @@ -662,6 +677,9 @@ static int __mptcp_setsockopt_sol_tcp_cork(struct mptcp_sock *msk, int val) struct mptcp_subflow_context *subflow; struct sock *sk = (struct sock *)msk; + if (has_current_bpf_ctx()) + return -EOPNOTSUPP; + sockopt_seq_inc(msk); msk->cork = !!val; mptcp_for_each_subflow(msk, subflow) { @@ -682,6 +700,9 @@ static int __mptcp_setsockopt_sol_tcp_nodelay(struct mptcp_sock *msk, int val) struct mptcp_subflow_context *subflow; struct sock *sk = (struct sock *)msk; + if (has_current_bpf_ctx()) + return -EOPNOTSUPP; + sockopt_seq_inc(msk); msk->nodelay = !!val; mptcp_for_each_subflow(msk, subflow) { @@ -749,6 +770,9 @@ static int mptcp_setsockopt_v4_set_tos(struct mptcp_sock *msk, int optname, struct sock *sk = (struct sock *)msk; int err, val; + if (has_current_bpf_ctx()) + return -EOPNOTSUPP; + err = ip_setsockopt(sk, SOL_IP, optname, optval, optlen); if (err != 0) @@ -1632,6 +1656,9 @@ int mptcp_set_rcvlowat(struct sock *sk, int val) if (sk->sk_protocol == IPPROTO_TCP) return -EINVAL; + if (has_current_bpf_ctx()) + return -EOPNOTSUPP; + if (sk->sk_userlocks & SOCK_RCVBUF_LOCK) cap = sk->sk_rcvbuf >> 1; else -- 2.43.0