@@ -261,6 +261,8 @@ bpf_iter_mptcp_subflow_new(struct bpf_iter_mptcp_subflow *it,
return -EINVAL;
msk = mptcp_sk(sk);
+ if (!mptcp_check_bpf_iter_task(msk))
+ return -EINVAL;
msk_owned_by_me(msk);
@@ -2729,6 +2729,7 @@ static void __mptcp_init_sock(struct sock *sk)
inet_csk(sk)->icsk_sync_mss = mptcp_sync_mss;
WRITE_ONCE(msk->csum_enabled, mptcp_is_checksum_enabled(sock_net(sk)));
WRITE_ONCE(msk->allow_infinite_fallback, true);
+ mptcp_clear_bpf_iter_task(msk);
msk->recovery = false;
msk->subflow_id = 1;
msk->last_data_sent = tcp_jiffies32;
@@ -334,6 +334,7 @@ struct mptcp_sock {
*/
struct mptcp_pm_data pm;
struct mptcp_sched_ops *sched;
+ struct task_struct *bpf_iter_task;
struct {
u32 space; /* bytes copied in last measurement window */
u32 copied; /* bytes copied in this measurement window */
@@ -1291,4 +1292,23 @@ mptcp_token_join_cookie_init_state(struct mptcp_subflow_request_sock *subflow_re
static inline void mptcp_join_cookie_init(void) {}
#endif
+static inline void mptcp_set_bpf_iter_task(struct mptcp_sock *msk)
+{
+ WRITE_ONCE(msk->bpf_iter_task, current);
+}
+
+static inline void mptcp_clear_bpf_iter_task(struct mptcp_sock *msk)
+{
+ WRITE_ONCE(msk->bpf_iter_task, NULL);
+}
+
+static inline bool mptcp_check_bpf_iter_task(struct mptcp_sock *msk)
+{
+ struct task_struct *task = READ_ONCE(msk->bpf_iter_task);
+
+ if (task && task == current)
+ return true;
+ return false;
+}
+
#endif /* __MPTCP_PROTOCOL_H */
@@ -155,6 +155,7 @@ void mptcp_subflow_set_scheduled(struct mptcp_subflow_context *subflow,
int mptcp_sched_get_send(struct mptcp_sock *msk)
{
struct mptcp_subflow_context *subflow;
+ int ret;
msk_owned_by_me(msk);
@@ -176,12 +177,16 @@ int mptcp_sched_get_send(struct mptcp_sock *msk)
if (msk->sched == &mptcp_sched_default || !msk->sched)
return mptcp_sched_default_get_send(msk);
- return msk->sched->get_send(msk);
+ mptcp_set_bpf_iter_task(msk);
+ ret = msk->sched->get_send(msk);
+ mptcp_clear_bpf_iter_task(msk);
+ return ret;
}
int mptcp_sched_get_retrans(struct mptcp_sock *msk)
{
struct mptcp_subflow_context *subflow;
+ int ret;
msk_owned_by_me(msk);
@@ -196,7 +201,9 @@ int mptcp_sched_get_retrans(struct mptcp_sock *msk)
if (msk->sched == &mptcp_sched_default || !msk->sched)
return mptcp_sched_default_get_retrans(msk);
- if (msk->sched->get_retrans)
- return msk->sched->get_retrans(msk);
- return msk->sched->get_send(msk);
+ mptcp_set_bpf_iter_task(msk);
+ ret = msk->sched->get_retrans ? msk->sched->get_retrans(msk) :
+ msk->sched->get_send(msk);
+ mptcp_clear_bpf_iter_task(msk);
+ return ret;
}