Netdev List
 help / color / mirror / Atom feed
* [PATCH net v2 1/2] llc: conn: use one state snapshot in llc_conn_service
@ 2026-06-08  7:46 Ren Wei
  2026-06-08  7:46 ` [PATCH net v2 2/2] llc: conn: publish OUT_OF_SVC before draining timers Ren Wei
  2026-06-10  1:58 ` [PATCH net v2 1/2] llc: conn: use one state snapshot in llc_conn_service Jakub Kicinski
  0 siblings, 2 replies; 3+ messages in thread
From: Ren Wei @ 2026-06-08  7:46 UTC (permalink / raw)
  To: netdev; +Cc: yuantan098, yifanwucs, tomapufckgml, bird, zcliangcn, n05ec

From: Zhengchuan Liang <zcliangcn@gmail.com>

llc_conn_service() only rejects states above NBR_CONN_STATES before
the state machine lookup. That misses LLC_CONN_OUT_OF_SVC, whose value
is 0.

The LLC state machine can set a socket to LLC_CONN_OUT_OF_SVC, and
llc_conn_disc() does not actually detach or free that socket yet. A
later packet can therefore reach llc_qualify_conn_ev() with state 0,
which indexes llc_conn_state_table[state - 1] and turns the lookup
into an out-of-bounds access.

Take one READ_ONCE() snapshot in llc_conn_service(), reject
LLC_CONN_OUT_OF_SVC there, and pass the validated state down to
llc_qualify_conn_ev(). This also keeps the lookup on one consistent
state value.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reported-by: Yuan Tan <yuantan098@gmail.com>
Reported-by: Yifan Wu <yifanwucs@gmail.com>
Reported-by: Juefei Pu <tomapufckgml@gmail.com>
Reported-by: Xin Liu <bird@lzu.edu.cn>
Assisted-by: Codex:GPT-5.4
Signed-off-by: Zhengchuan Liang <zcliangcn@gmail.com>
Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
---
changes in v2:
  - Use a single READ_ONCE() snapshot of llc->state in llc_conn_service().
  - Pass the validated state into llc_qualify_conn_ev() to avoid mixed state reads.
  - v1 link: https://lore.kernel.org/all/5f646c530f4a0820060499054c46b8dbecebd7be.1778638129.git.zlian064@ucr.edu/


 net/llc/llc_conn.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c
index 5c0ac243b248..9602183d09d8 100644
--- a/net/llc/llc_conn.c
+++ b/net/llc/llc_conn.c
@@ -37,7 +37,8 @@ static int llc_exec_conn_trans_actions(struct sock *sk,
 				       const struct llc_conn_state_trans *trans,
 				       struct sk_buff *ev);
 static const struct llc_conn_state_trans *llc_qualify_conn_ev(struct sock *sk,
-							      struct sk_buff *skb);
+							      struct sk_buff *skb,
+							      u8 state);
 
 /* Offset table on connection states transition diagram */
 static int llc_offset_table[NBR_CONN_STATES][NBR_CONN_EV];
@@ -358,12 +359,15 @@ static int llc_conn_service(struct sock *sk, struct sk_buff *skb)
 {
 	const struct llc_conn_state_trans *trans;
 	struct llc_sock *llc = llc_sk(sk);
+	u8 state = READ_ONCE(llc->state);
 	int rc = 1;
 
-	if (llc->state > NBR_CONN_STATES)
+	if (state == LLC_CONN_OUT_OF_SVC)
+		return 0;
+	if (state > NBR_CONN_STATES)
 		goto out;
 	rc = 0;
-	trans = llc_qualify_conn_ev(sk, skb);
+	trans = llc_qualify_conn_ev(sk, skb, state);
 	if (trans) {
 		rc = llc_exec_conn_trans_actions(sk, trans, skb);
 		if (!rc && trans->next_state != NO_STATE_CHANGE) {
@@ -385,20 +389,20 @@ static int llc_conn_service(struct sock *sk, struct sk_buff *skb)
  *	Returns pointer to found transition on success, %NULL otherwise.
  */
 static const struct llc_conn_state_trans *llc_qualify_conn_ev(struct sock *sk,
-							      struct sk_buff *skb)
+							      struct sk_buff *skb,
+							      u8 state)
 {
 	const struct llc_conn_state_trans **next_trans;
 	const llc_conn_ev_qfyr_t *next_qualifier;
 	struct llc_conn_state_ev *ev = llc_conn_ev(skb);
-	struct llc_sock *llc = llc_sk(sk);
 	struct llc_conn_state *curr_state =
-					&llc_conn_state_table[llc->state - 1];
+					&llc_conn_state_table[state - 1];
 
 	/* search thru events for this state until
 	 * list exhausted or until no more
 	 */
 	for (next_trans = curr_state->transitions +
-		llc_find_offset(llc->state - 1, ev->type);
+		llc_find_offset(state - 1, ev->type);
 	     (*next_trans)->ev; next_trans++) {
 		if (!((*next_trans)->ev)(sk, skb)) {
 			/* got POSSIBLE event match; the event may require
-- 
2.47.3


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-06-10  1:58 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-08  7:46 [PATCH net v2 1/2] llc: conn: use one state snapshot in llc_conn_service Ren Wei
2026-06-08  7:46 ` [PATCH net v2 2/2] llc: conn: publish OUT_OF_SVC before draining timers Ren Wei
2026-06-10  1:58 ` [PATCH net v2 1/2] llc: conn: use one state snapshot in llc_conn_service Jakub Kicinski

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox