6a58da
From ba2ee4b6dc9874de0de26ad4b03c59b179f5dbe5 Mon Sep 17 00:00:00 2001
6a58da
From: Xin Long <lucien.xin@gmail.com>
6a58da
Date: Fri, 18 Nov 2022 16:45:01 -0500
6a58da
Subject: [PATCH 2/2] tipc: add an extra conn_get in tipc_conn_alloc
6a58da
Git-commit: a7b42969d63f47320853a802efd879fbdc4e010e
6a58da
Patch-mainline: v6.1-rc7
6a58da
References: bsc#1209288 CVE-2023-1382
6a58da
6a58da
One extra conn_get() is needed in tipc_conn_alloc(), as after
6a58da
tipc_conn_alloc() is called, tipc_conn_close() may free this
6a58da
con before deferencing it in tipc_topsrv_accept():
6a58da
6a58da
   tipc_conn_alloc();
6a58da
   newsk = newsock->sk;
6a58da
                                 <---- tipc_conn_close();
6a58da
   write_lock_bh(&sk->sk_callback_lock);
6a58da
   newsk->sk_data_ready = tipc_conn_data_ready;
6a58da
6a58da
Then an uaf issue can be triggered:
6a58da
6a58da
  BUG: KASAN: use-after-free in tipc_topsrv_accept+0x1e7/0x370 [tipc]
6a58da
  Call Trace:
6a58da
   <TASK>
6a58da
   dump_stack_lvl+0x33/0x46
6a58da
   print_report+0x178/0x4b0
6a58da
   kasan_report+0x8c/0x100
6a58da
   kasan_check_range+0x179/0x1e0
6a58da
   tipc_topsrv_accept+0x1e7/0x370 [tipc]
6a58da
   process_one_work+0x6a3/0x1030
6a58da
   worker_thread+0x8a/0xdf0
6a58da
6a58da
This patch fixes it by holding it in tipc_conn_alloc(), then after
6a58da
all accessing in tipc_topsrv_accept() releasing it. Note when does
6a58da
this in tipc_topsrv_kern_subscr(), as tipc_conn_rcv_sub() returns
6a58da
0 or -1 only, we don't need to check for "> 0".
6a58da
6a58da
Fixes: c5fa7b3cf3cb ("tipc: introduce new TIPC server infrastructure")
6a58da
Signed-off-by: Xin Long <lucien.xin@gmail.com>
6a58da
Acked-by: Jon Maloy <jmaloy@redhat.com>
6a58da
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
6a58da
Signed-off-by: Denis Kirjanov <denis.kirjanov@suse.com>
6a58da
---
6a58da
 net/tipc/topsrv.c | 9 ++++++---
6a58da
 1 file changed, 6 insertions(+), 3 deletions(-)
6a58da
6a58da
diff --git a/net/tipc/topsrv.c b/net/tipc/topsrv.c
6a58da
index 61e9828a76cd..1a3d9837ac6a 100644
6a58da
--- a/net/tipc/topsrv.c
6a58da
+++ b/net/tipc/topsrv.c
6a58da
@@ -206,6 +206,7 @@ static struct tipc_conn *tipc_conn_alloc(struct tipc_topsrv *s, struct socket *s
6a58da
 	set_bit(CF_CONNECTED, &con->flags);
6a58da
 	con->server = s;
6a58da
 	con->sock = sock;
6a58da
+	conn_get(con);
6a58da
 	spin_unlock_bh(&s->idr_lock);
6a58da
 
6a58da
 	return con;
6a58da
@@ -474,6 +475,7 @@ static void tipc_topsrv_accept(struct work_struct *work)
6a58da
 
6a58da
 		/* Wake up receive process in case of 'SYN+' message */
6a58da
 		newsk->sk_data_ready(newsk);
6a58da
+		conn_put(con);
6a58da
 	}
6a58da
 }
6a58da
 
6a58da
@@ -573,10 +575,11 @@ bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, u32 lower,
6a58da
 
6a58da
 	*conid = con->conid;
6a58da
 	rc = tipc_conn_rcv_sub(tipc_topsrv(net), con, &sub);
6a58da
-	if (rc >= 0)
6a58da
-		return true;
6a58da
+	if (rc)
6a58da
+		conn_put(con);
6a58da
+
6a58da
 	conn_put(con);
6a58da
-	return false;
6a58da
+	return !rc;
6a58da
 }
6a58da
 
6a58da
 void tipc_topsrv_kern_unsubscr(struct net *net, int conid)
6a58da
-- 
6a58da
2.16.4
6a58da