diff mbox series

[net] mctp: perform route lookups under a RCU read-side lock

Message ID 29c4b0e67dc1bf3571df3982de87df90cae9b631.1696837310.git.jk@codeconstruct.com.au (mailing list archive)
State Accepted
Commit 5093bbfc10ab6636b32728e35813cbd79feb063c
Delegated to: Netdev Maintainers
Headers show
Series [net] mctp: perform route lookups under a RCU read-side lock | expand

Checks

Context Check Description
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for net
netdev/fixes_present success Fixes tag present in non-next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 1367 this patch: 1367
netdev/cc_maintainers success CCed 7 of 7 maintainers
netdev/build_clang success Errors and warnings before: 1388 this patch: 1388
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 1391 this patch: 1391
netdev/checkpatch warning WARNING: 'premption' may be misspelled - perhaps 'preemption'?
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Jeremy Kerr Oct. 9, 2023, 7:56 a.m. UTC
Our current route lookups (mctp_route_lookup and mctp_route_lookup_null)
traverse the net's route list without the RCU read lock held. This means
the route lookup is subject to preemption, resulting in an potential
grace period expiry, and so an eventual kfree() while we still have the
route pointer.

Add the proper read-side critical section locks around the route
lookups, preventing premption and a possible parallel kfree.

The remaining net->mctp.routes accesses are already under a
rcu_read_lock, or protected by the RTNL for updates.

Based on an analysis from Sili Luo <rootlab@huawei.com>, where
introducing a delay in the route lookup could cause a UAF on
simultaneous sendmsg() and route deletion.

Reported-by: Sili Luo <rootlab@huawei.com>
Fixes: 889b7da23abf ("mctp: Add initial routing framework")
Cc: stable@vger.kernel.org
Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
---
 net/mctp/route.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

Comments

Eric Dumazet Oct. 9, 2023, 8:13 a.m. UTC | #1
On Mon, Oct 9, 2023 at 9:57 AM Jeremy Kerr <jk@codeconstruct.com.au> wrote:
>
> Our current route lookups (mctp_route_lookup and mctp_route_lookup_null)
> traverse the net's route list without the RCU read lock held. This means
> the route lookup is subject to preemption, resulting in an potential
> grace period expiry, and so an eventual kfree() while we still have the
> route pointer.
>
> Add the proper read-side critical section locks around the route
> lookups, preventing premption and a possible parallel kfree.
>
> The remaining net->mctp.routes accesses are already under a
> rcu_read_lock, or protected by the RTNL for updates.
>
> Based on an analysis from Sili Luo <rootlab@huawei.com>, where
> introducing a delay in the route lookup could cause a UAF on
> simultaneous sendmsg() and route deletion.
>
> Reported-by: Sili Luo <rootlab@huawei.com>
> Fixes: 889b7da23abf ("mctp: Add initial routing framework")
> Cc: stable@vger.kernel.org
> Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
> ---
>

Reviewed-by: Eric Dumazet <edumazet@google.com>
patchwork-bot+netdevbpf@kernel.org Oct. 11, 2023, 2:50 a.m. UTC | #2
Hello:

This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Mon,  9 Oct 2023 15:56:45 +0800 you wrote:
> Our current route lookups (mctp_route_lookup and mctp_route_lookup_null)
> traverse the net's route list without the RCU read lock held. This means
> the route lookup is subject to preemption, resulting in an potential
> grace period expiry, and so an eventual kfree() while we still have the
> route pointer.
> 
> Add the proper read-side critical section locks around the route
> lookups, preventing premption and a possible parallel kfree.
> 
> [...]

Here is the summary with links:
  - [net] mctp: perform route lookups under a RCU read-side lock
    https://git.kernel.org/netdev/net/c/5093bbfc10ab

You are awesome, thank you!
diff mbox series

Patch

diff --git a/net/mctp/route.c b/net/mctp/route.c
index f51a05ec7162..68be8f2b622d 100644
--- a/net/mctp/route.c
+++ b/net/mctp/route.c
@@ -737,6 +737,8 @@  struct mctp_route *mctp_route_lookup(struct net *net, unsigned int dnet,
 {
 	struct mctp_route *tmp, *rt = NULL;
 
+	rcu_read_lock();
+
 	list_for_each_entry_rcu(tmp, &net->mctp.routes, list) {
 		/* TODO: add metrics */
 		if (mctp_rt_match_eid(tmp, dnet, daddr)) {
@@ -747,21 +749,29 @@  struct mctp_route *mctp_route_lookup(struct net *net, unsigned int dnet,
 		}
 	}
 
+	rcu_read_unlock();
+
 	return rt;
 }
 
 static struct mctp_route *mctp_route_lookup_null(struct net *net,
 						 struct net_device *dev)
 {
-	struct mctp_route *rt;
+	struct mctp_route *tmp, *rt = NULL;
 
-	list_for_each_entry_rcu(rt, &net->mctp.routes, list) {
-		if (rt->dev->dev == dev && rt->type == RTN_LOCAL &&
-		    refcount_inc_not_zero(&rt->refs))
-			return rt;
+	rcu_read_lock();
+
+	list_for_each_entry_rcu(tmp, &net->mctp.routes, list) {
+		if (tmp->dev->dev == dev && tmp->type == RTN_LOCAL &&
+		    refcount_inc_not_zero(&tmp->refs)) {
+			rt = tmp;
+			break;
+		}
 	}
 
-	return NULL;
+	rcu_read_unlock();
+
+	return rt;
 }
 
 static int mctp_do_fragment_route(struct mctp_route *rt, struct sk_buff *skb,