[PR #63] [CLOSED] core: rtw_ieee80211: guard attr_len underflow in rtw_get_wfd_attr_content #66

Closed
opened 2026-10-13 19:33:52 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morrownr/8812au-20210820/pull/63
Author: @breakneck-git
Created: 4/26/2026
Status: ❌ Closed

Base: main ← Head: fix-p2p-wfd-attr-len-underflow


📝 Commits (1)

  • 5d98510 core: rtw_ieee80211: guard attr_len underflow in rtw_get_wfd_attr_content

📊 Changes

1 file changed (+15 additions, -1 deletions)

View changed files

📝 core/rtw_ieee80211.c (+15 -1)

📄 Description

Summary

Guards against an integer underflow in rtw_get_wfd_attr_content() that, on a malformed Wi-Fi-Display attribute, leads to _rtw_memcpy() writing a near-INT_MAX number of bytes into a kernel stack buffer.

Why only WFD here

This fork's rtw_get_p2p_attr_content() (same file, just above) already uses a bounds-safe pattern — callers pre-populate *len_content with sizeof(buf) and the function clamps the copy to that hint. Whoever did that hardening pass apparently missed rtw_get_wfd_attr_content() right below it; this PR addresses just the missed variant.

The same class of bug was also submitted to:

Root cause

attr_ptr = rtw_get_wfd_attr(wfd_ie, wfd_ielen, target_attr_id, NULL, &attr_len);
if (attr_ptr && attr_len) {
    if (buf_content)
        _rtw_memcpy(buf_content, attr_ptr + 3, attr_len - 3);   // ← underflow
    ...

attr_len carries the 3-byte WFD attribute header. The parser computes attr_len = attr_data_len + 3 with both operands u16. When attr_data_len >= 0xFFFD (attacker-controlled length field in frame), the addition wraps in u16 to {0, 1, 2}. The parser's bounds check only catches attr_len > wfd_ielen, not the wrap.

When attr_len < 3 reaches the callee, attr_len - 3 underflows in u32 to a near-INT_MAX value, and _rtw_memcpy(buf_content, attr_ptr + 3, ~0xFFFFFFFE) runs.

Fix

Replace attr_len truthiness check with attr_len >= 3 (the documented minimum). When the parser returns underflowed attr_len < 3, the callee now returns NULL with *len_content == 0, matching the documented "attribute not found" return path that all callers already handle.

A follow-up to mirror the P2P pattern (caller-supplied bounds via *len_content) here would also be valid — happy to do it as a separate PR if you prefer.

Test environment

  • Realtek 8821AU (USB ID 0bda:0811) on Raspberry Pi 2B, kernel 6.12.47
  • Static analysis only; not runtime-fuzzed (the trigger requires a crafted 802.11 WFD action frame)

Disclosure

This patch is the result of a code-review pass conducted with the help of an LLM (Claude). The reasoning, exploit chain, and fix were verified by reading the relevant source paths exhaustively before submission. I am not a kernel engineer; please flag anything I missed.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morrownr/8812au-20210820/pull/63 **Author:** [@breakneck-git](https://github.com/breakneck-git) **Created:** 4/26/2026 **Status:** ❌ Closed **Base:** `main` ← **Head:** `fix-p2p-wfd-attr-len-underflow` --- ### 📝 Commits (1) - [`5d98510`](https://github.com/morrownr/8812au-20210820/commit/5d985108a87b9a5f1fbf3fe6f2c12dfc8d6b5254) core: rtw_ieee80211: guard attr_len underflow in rtw_get_wfd_attr_content ### 📊 Changes **1 file changed** (+15 additions, -1 deletions) <details> <summary>View changed files</summary> 📝 `core/rtw_ieee80211.c` (+15 -1) </details> ### 📄 Description ## Summary Guards against an integer underflow in `rtw_get_wfd_attr_content()` that, on a malformed Wi-Fi-Display attribute, leads to `_rtw_memcpy()` writing a near-INT_MAX number of bytes into a kernel stack buffer. ## Why only WFD here This fork's `rtw_get_p2p_attr_content()` (same file, just above) **already uses a bounds-safe pattern** — callers pre-populate `*len_content` with `sizeof(buf)` and the function clamps the copy to that hint. Whoever did that hardening pass apparently missed `rtw_get_wfd_attr_content()` right below it; this PR addresses just the missed variant. The same class of bug was also submitted to: - [aircrack-ng/rtl8812au#1258](https://github.com/aircrack-ng/rtl8812au/pull/1258) — fixes both P2P and WFD (their P2P function still has the unhardened pattern) - [morrownr/8821au-20210708#199](https://github.com/morrownr/8821au-20210708/pull/199) — same as aircrack-ng (sister 8821au repo also has unhardened P2P) ## Root cause ```c attr_ptr = rtw_get_wfd_attr(wfd_ie, wfd_ielen, target_attr_id, NULL, &attr_len); if (attr_ptr && attr_len) { if (buf_content) _rtw_memcpy(buf_content, attr_ptr + 3, attr_len - 3); // ← underflow ... ``` `attr_len` carries the 3-byte WFD attribute header. The parser computes `attr_len = attr_data_len + 3` with **both operands `u16`**. When `attr_data_len >= 0xFFFD` (attacker-controlled length field in frame), the addition wraps in `u16` to `{0, 1, 2}`. The parser's bounds check only catches `attr_len > wfd_ielen`, not the wrap. When `attr_len < 3` reaches the callee, `attr_len - 3` underflows in `u32` to a near-INT_MAX value, and `_rtw_memcpy(buf_content, attr_ptr + 3, ~0xFFFFFFFE)` runs. ## Fix Replace `attr_len` truthiness check with `attr_len >= 3` (the documented minimum). When the parser returns underflowed `attr_len < 3`, the callee now returns NULL with `*len_content == 0`, matching the documented "attribute not found" return path that all callers already handle. A follow-up to mirror the P2P pattern (caller-supplied bounds via `*len_content`) here would also be valid — happy to do it as a separate PR if you prefer. ## Test environment - Realtek 8821AU (USB ID `0bda:0811`) on Raspberry Pi 2B, kernel 6.12.47 - Static analysis only; not runtime-fuzzed (the trigger requires a crafted 802.11 WFD action frame) ## Disclosure This patch is the result of a code-review pass conducted with the help of an LLM (Claude). The reasoning, exploit chain, and fix were verified by reading the relevant source paths exhaustively before submission. I am not a kernel engineer; please flag anything I missed. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-13 19:33:52 +00:00
Sign in to join this conversation.
No labels
bug
bug
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morrownr/8812au-20210820#66
No description provided.