llc_conn_service() checks only the upper bound of the connection state before llc_qualify_conn_ev() indexes the state table. A socket in LLC_CONN_OUT_OF_SVC therefore reaches llc_conn_state_table[state - 1] with a negative index and can read and call data outside the table. Reject states below LLC_CONN_STATE_ADM before the state-table lookup. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Reported-by: Vega Assisted-by: Codex:gpt-5.4 Signed-off-by: Zihan Xi --- changes in v6: - Hold a reference for children queued for accept() and release it when they are dequeued, while retaining SAP publication so tuple lookup still finds a pending child before the passive open completes. - Make direct receive, backlog, accept-queue, and listener-close cleanup symmetric, with bottom-half-disabled child locking in process context. - Keep the LLC_CONN_OUT_OF_SVC lower-bound check in its separate patch and use the ADM state boundary consistently. - v5 Link: https://lore.kernel.org/all/20260822082354.3109-1-zihanx@nebusec.ai/ changes in v5: - Make listener child cleanup unconditional so queued children are also released if the socket leaves TCP_LISTEN before close. - Serialize process-context child cleanup and backlog dispatch with bottom halves disabled, avoiding child-lock acquisition races with LLC receive and timer paths. - Drop packets redirected through a pending child after its listener is no longer listening, and release children left out of service instead of dispatching them. - Split the LLC_CONN_OUT_OF_SVC lower-bound check into a separate patch. - v4 Link: https://lore.kernel.org/all/20260814185843.4748-1-zihanx@nebusec.ai/ changes in v4: - Create a passive-open child only for SABME and generate listener-side DM replies directly for non-SABME commands. - Use an atomic incoming-child lifecycle and serialize pending-child lookup, backlog processing, rollback, and listener close with the child lock. - Keep immediate SAP publication for passive-open tuple matching, but release unaccepted children on direct and backlog failures and on listener close. - Defer final incoming-child cleanup to workqueue context so timer synchronization does not run in the receive softirq path. - Add an LLC state lower-bound check before state-table dispatch. - v3 Link: https://lore.kernel.org/all/20260805175945.10698-1-zihanx@nebusec.ai/ changes in v3: - Drop the unused llc_conn_handler() local rc variable reported in review. - Rebase the numbered patch and cover onto commit ede76849012e45ffb2193ad110b42027eec02c5c. - v2 Link: https://lore.kernel.org/all/cover.1785386749.git.zihanx@nebusec.ai/ changes in v2: - Rework the fix to preserve the existing passive-open tuple matching semantics instead of deferring child publication until LLC_CONN_PRIM. - Track listener-created children pending publication to accept(), and roll them back on every earlier failure or drop path. - Cover the original non-SABME leak and SABME paths which fail before LLC_CONN_PRIM, including backlog enqueue and backlog drop failures. - Correct Fixes to 1da177e4c3f4 ("Linux-2.6.12-rc2") based on the earliest locally visible history carrying the same root-cause fact. - Clarify panic_on_oom crash evidence and packetdrill selection. - v1 Link: https://lore.kernel.org/all/cover.1784725007.git.zihanx@nebusec.ai/ net/llc/llc_conn.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c index 885a5c33024c..4a34f240ad2c 100644 --- a/net/llc/llc_conn.c +++ b/net/llc/llc_conn.c @@ -362,7 +362,8 @@ static int llc_conn_service(struct sock *sk, struct sk_buff *skb) struct llc_sock *llc = llc_sk(sk); int rc = 1; - if (llc->state > NBR_CONN_STATES) + if (llc->state < LLC_CONN_STATE_ADM || + llc->state > NBR_CONN_STATES) goto out; rc = 0; trans = llc_qualify_conn_ev(sk, skb); -- 2.43.0