From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0033A397ACC; Wed, 7 Jan 2026 15:53:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767801228; cv=none; b=k350sGNdBtR2+efXSNusMVrJosioW1rAdWYE9KmG6kh1ZP61Gkdr9pMMfU0igPjir9BCzSmyLoL0T9i/pA5BlnxDhHn/d84WJr+9ax5PZy2avZ6fcmYqpfsNSP2HGEBcxOli3b9lwHY1f63hSpGaQxsLrKY4ELThhppbH68l47Y= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767801228; c=relaxed/simple; bh=QUsVMu+wmJmPa4Y3bc659Yy2m3ZzKZ2vIGmrTzq6TTE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=tzQitG+YFbG67iLdgThzGgADG7E6kVJEqeO72kBO/UgxMGesTsPQsTvAx5Y3E+mz2GQ5PAwTGnY7+NQ22/U1AEMr4amtdfGgct7KvkX0yNjbRvZt2Og4JCQ1htWGrqbSzhi7ZO68XfF1E4U7d2+otTBRNd5thEw8+/UCl25jyaY= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=XfYMaYN8; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="XfYMaYN8" Received: by smtp.kernel.org (Postfix) with ESMTPSA id F1686C4CEF1; Wed, 7 Jan 2026 15:53:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1767801225; bh=QUsVMu+wmJmPa4Y3bc659Yy2m3ZzKZ2vIGmrTzq6TTE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XfYMaYN8ZBCb2j0uJcwyJ2i9ovaKd7Ldm5L6wbmkbOHQB/6j/GZnDDpGJu1IB4Ks4 5ocZMQaUNrhv+3eWOsOGA2K7nORkM+Ly/FUn0BGz9A66loDRQrsk667fL/qbQFyJUX NTG2T3ZyG7XN3QD1RxE4HtwzH3Ss4A/vSn/9l1CM6GzTCkciMnXb47zcRHuqIA2HUM J4YiqZqZ1qkotVT3YzHXbptjz+uWGwFfKdZ2nAW6TIggpWkdWAb3MeyjyuiLe6dng0 RFaAYmPwbT+pkKoanuaWX5eJYuldPWneybkeiw3kjecxKrVInV9vF/KPKLOTe4C1RG w3WmKnG2J439g== From: Sasha Levin To: patches@lists.linux.dev, stable@vger.kernel.org Cc: =?UTF-8?q?Peter=20=C3=85strand?= , Johannes Berg , Sasha Levin , sakari.ailus@linux.intel.com Subject: [PATCH AUTOSEL 6.18-5.10] wifi: wlcore: ensure skb headroom before skb_push Date: Wed, 7 Jan 2026 10:53:11 -0500 Message-ID: <20260107155329.4063936-9-sashal@kernel.org> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260107155329.4063936-1-sashal@kernel.org> References: <20260107155329.4063936-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore X-stable-base: Linux 6.18.3 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Peter Åstrand [ Upstream commit e75665dd096819b1184087ba5718bd93beafff51 ] This avoids occasional skb_under_panic Oops from wl1271_tx_work. In this case, headroom is less than needed (typically 110 - 94 = 16 bytes). Signed-off-by: Peter Astrand Link: https://patch.msgid.link/097bd417-e1d7-acd4-be05-47b199075013@lysator.liu.se Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin --- LLM Generated explanations, may be completely bogus: ## Commit Analysis: wifi: wlcore: ensure skb headroom before skb_push ### 1. COMMIT MESSAGE ANALYSIS **Key indicators:** - Subject clearly states this ensures skb headroom before skb_push - a defensive check - Body explicitly states: "This avoids occasional skb_under_panic Oops from wl1271_tx_work" - Provides specific details: "headroom is less than needed (typically 110 - 94 = 16 bytes)" - Committed by Johannes Berg (wireless maintainer) The commit message clearly indicates this fixes a **kernel panic** - one of the most severe bug categories. ### 2. CODE CHANGE ANALYSIS Let me examine the actual code change: ```c if (total_blocks <= wl->tx_blocks_available) { + if (skb_headroom(skb) < (total_len - skb->len) && + pskb_expand_head(skb, (total_len - skb->len), 0, GFP_ATOMIC)) { + wl1271_free_tx_id(wl, id); + return -EAGAIN; + } desc = skb_push(skb, total_len - skb->len); ``` **The bug mechanism:** - `skb_push()` prepends space to an skb to add the TX hardware descriptor - If the skb doesn't have sufficient headroom, `skb_push()` triggers `skb_under_panic()` - a kernel Oops - The original code assumed sufficient headroom always existed, which is incorrect **The fix mechanism:** 1. Check if headroom is insufficient: `skb_headroom(skb) < (total_len - skb->len)` 2. If insufficient, call `pskb_expand_head()` to expand the buffer 3. On expansion failure (memory pressure), properly cleanup by freeing the tx_id 4. Return `-EAGAIN` to indicate temporary failure (allows retry) 5. Only proceed with `skb_push()` after headroom is guaranteed **Technical correctness:** - Uses `GFP_ATOMIC` - correct for TX path which may hold locks - Properly frees the allocated `id` on failure path (no resource leak) - Returns `-EAGAIN` which is the appropriate error for temporary failures - This is a well-established kernel pattern for skb headroom handling ### 3. CLASSIFICATION **Type:** Bug fix - fixes a kernel panic (skb_under_panic Oops) **Not in exception categories** - this is a straight bug fix for a crash, not a device ID, quirk, DT update, or build fix. ### 4. SCOPE AND RISK ASSESSMENT | Metric | Assessment | |--------|------------| | Lines added | +5 lines of actual logic | | Files changed | 1 file | | Complexity | Very low - standard skb headroom check pattern | | Risk | **Very low** - defensive check that cannot make things worse | **Failure mode analysis:** - If `pskb_expand_head()` fails: returns -EAGAIN, TX retries later (graceful degradation) - If check is overly conservative: no harm, just an extra allocation - Cannot introduce new crashes - the check is purely defensive ### 5. USER IMPACT **Affected users:** Users of TI WiLink WiFi hardware (wl12xx/wl18xx families) - Common in embedded systems, some laptops, IoT devices - This is a mature, production driver present in all stable trees **Bug severity:** **Critical** - kernel panic causes system crash - Even "occasional" panics are unacceptable in production - WiFi TX is a common operation, so affected users hit this repeatedly ### 6. STABILITY INDICATORS - Reviewed and accepted by wireless maintainer (Johannes Berg) - Simple, well-understood pattern used throughout the kernel - The fix has minimal side effects - worst case is a failed TX that retries ### 7. DEPENDENCY CHECK - **Standalone fix** - no dependencies on other commits - Uses standard kernel APIs (skb_headroom, pskb_expand_head) that exist in all stable trees - The wlcore driver has existed for many years in stable kernels ### SUMMARY **This is a textbook stable candidate:** 1. **Fixes a kernel panic** - the most critical bug category 2. **Small and surgical** - 5 lines of defensive checking 3. **Obviously correct** - standard skb headroom pattern used throughout kernel 4. **Zero regression risk** - purely defensive, cannot make things worse 5. **No new features** - just adds a safety check before existing operation 6. **Affects real users** - wlcore is a production driver for shipping hardware 7. **No dependencies** - applies cleanly to any kernel version with wlcore The fix prevents a real kernel Oops that users encounter in production. The change is minimal, the pattern is well-established, and the risk of regression is essentially zero. This is exactly the type of fix that stable kernel rules are designed to accept. **YES** drivers/net/wireless/ti/wlcore/tx.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c index 464587d16ab2..f251627c24c6 100644 --- a/drivers/net/wireless/ti/wlcore/tx.c +++ b/drivers/net/wireless/ti/wlcore/tx.c @@ -207,6 +207,11 @@ static int wl1271_tx_allocate(struct wl1271 *wl, struct wl12xx_vif *wlvif, total_blocks = wlcore_hw_calc_tx_blocks(wl, total_len, spare_blocks); if (total_blocks <= wl->tx_blocks_available) { + if (skb_headroom(skb) < (total_len - skb->len) && + pskb_expand_head(skb, (total_len - skb->len), 0, GFP_ATOMIC)) { + wl1271_free_tx_id(wl, id); + return -EAGAIN; + } desc = skb_push(skb, total_len - skb->len); wlcore_hw_set_tx_desc_blocks(wl, desc, total_blocks, -- 2.51.0