On Wed, Oct 30, 2024 at 3:02 PM Breno Leitao <leitao@xxxxxxxxxx> wrote: > > The mptcp_sched_find() function must be called with the RCU read lock > held, as it accesses RCU-protected data structures. This requirement was > not properly enforced in the mptcp_init_sock() function, leading to a > RCU list traversal in a non-reader section error when > CONFIG_PROVE_RCU_LIST is enabled. > > net/mptcp/sched.c:44 RCU-list traversed in non-reader section!! > > Fix it by acquiring the RCU read lock before calling the > mptcp_sched_find() function. This ensures that the function is invoked > with the necessary RCU protection in place, as it accesses RCU-protected > data structures. > > Additionally, the patch breaks down the mptcp_init_sched() call into > smaller parts, with the RCU read lock only covering the specific call to > mptcp_sched_find(). This helps minimize the critical section, reducing > the time during which RCU grace periods are blocked. > > The mptcp_sched_list_lock is not held in this case, and it is not clear > if it is necessary. > > Signed-off-by: Breno Leitao <leitao@xxxxxxxxxx> > Fixes: 1730b2b2c5a5 ("mptcp: add sched in mptcp_sock") > Cc: stable@xxxxxxxxxxxxxxx > --- > net/mptcp/protocol.c | 7 +++++-- > 1 file changed, 5 insertions(+), 2 deletions(-) > > diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c > index 6d0e201c3eb2..8ece630f80d4 100644 > --- a/net/mptcp/protocol.c > +++ b/net/mptcp/protocol.c > @@ -2854,6 +2854,7 @@ static void mptcp_ca_reset(struct sock *sk) > static int mptcp_init_sock(struct sock *sk) > { > struct net *net = sock_net(sk); > + struct mptcp_sched_ops *sched; > int ret; > > __mptcp_init_sock(sk); > @@ -2864,8 +2865,10 @@ static int mptcp_init_sock(struct sock *sk) > if (unlikely(!net->mib.mptcp_statistics) && !mptcp_mib_alloc(net)) > return -ENOMEM; > > - ret = mptcp_init_sched(mptcp_sk(sk), > - mptcp_sched_find(mptcp_get_scheduler(net))); > + rcu_read_lock(); > + sched = mptcp_sched_find(mptcp_get_scheduler(net)); > + rcu_read_unlock(); You are silencing the warning, but a potential UAF remains. sched could have been freed already, it is illegal to deref it. > + ret = mptcp_init_sched(mptcp_sk(sk), sched); The rcu_read_unlock() should be moved after this point. This means that mptcp_sched_ops ->init() functions are not allowed to sleep. > if (ret) > return ret; > > -- > 2.43.5 >