[Bug] raw-API DHCP server reads client option values without bounds checks (OOB read)
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 78/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- c
- Domain
- networking, security
Research direction
Read components/net/lwip-dhcpd/dhcp_server_raw.c, starting with dhcp_server_option_find and its callers at the cited lines; compare their checks with the socket-based dhcp_server.c. Verify option header bounds and declared value lengths before reads, then confirm truncated options are rejected and valid DHCP options still dispatch correctly.
Written by the indexing model from the issue text.
Description
RT-Thread Version
master @ 1c801efabc.
Affected area
Networking
Hardware/BSP vendor
Not applicable / Other
Architecture
Not applicable / Other
Board and hardware details
Not applicable.
Develop Toolchain
GCC
Describe the bug
The raw-API DHCP server parses client packets without bounding the option walk or the option-value reads.
components/net/lwip-dhcpd/dhcp_server_raw.c:296:
static u8_t *dhcp_server_option_find(u8_t *buf, u16_t len, u8_t option) {
u8_t *end = buf + len;
while ((buf < end) && (*buf != DHCP_OPTION_END)) {
if (*buf == option) return buf;
buf += (buf[1] + 2); /* buf[1] read even when buf == end-1 */
}
return NULL;
}
buf[1] is read without verifying buf + 1 < end, so a final option header at end-1 reads one byte past the buffer. The function also only guarantees the returned pointer is < end, and the callers read the value with no length check:
node = dhcp_client_find_by_ip(dhcpserver, (ip4_addr_t *)(&opt[2])); /* :209, reads 4 bytes */
msg_type = *(opt + 2); /* :372 */
A REQUESTED_IP (50) or MESSAGE_TYPE (53) option placed at the tail lets opt[2]..opt[5] read up to 4 bytes past the buffer. The packet buffer is a fixed pbuf_alloc(PBUF_TRANSPORT, 1500, PBUF_RAM) (:331), so the over-reads land just past that heap allocation.
The sibling socket-based server dhcp_server.c performs exactly the checks this file omits (dhcp_opt + 2 > dhcp_opt_end, declared-length validation, length < 4 / length < 1), which confirms the raw variant is missing them.
Steps / trigger. Any host on the same L2 segment sends a DHCP packet to UDP/67 whose option area ends with a REQUESTED_IP / MESSAGE_TYPE option header positioned so its value bytes fall at or past the buffer end. No authentication. Reproduced at logic level under ASan (reports/repro/dhcpd-raw/).
Expected. Short or truncated options are rejected before their length/value bytes are read, as dhcp_server.c already does.
Actual. Out-of-bounds read of a few bytes past the 1500-byte heap allocation. The values are used only for dispatch / IP comparison and are not returned to the attacker, so the practical impact is a crash / DoS if the allocation abuts an unmapped page.
Suggested fix. Port the socket variant's checks: require buf + 1 < end before reading buf[1] and buf + 2 + buf[1] <= end before advancing; in each caller verify the matched option's declared length and that opt + 2 + opt[1] <= end before reading the value.
Other additional context
No response
- Dominant language
- C
- Stars
- 12.3k
- Forks
- 5.5k
- Avg merge
- 7d 22h
- Merged PRs (30d)
- 30
Getting set up
Starts the project's dev container in your browser, under your own GitHub account.
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from RT-Thread/rt-thread
-
[Bug] dfs_v2 tmpfs: ftruncate(fd, 0) frees the file buffer but reports success — use-after-free read/write and double free from a legal POSIX callPossibly taken @remukisama claimed this 1 day ago. Openin progress
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
RT-Thread/rt-thread#11902 · 4 comments · 1 assignee ·
Maintainers usually reply within 1 day
-
[bsp][stm32][bluepill] README「快速上手」缺少重新生成 MDK 工程这一步,按文档操作无法编译通过Possibly taken @moment-NEW claimed this 18 days ago. Openin progress
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
RT-Thread/rt-thread#11818 · 4 comments · 1 assignee ·
Maintainers usually reply within 1 day
-
BSP BSP: Loongson bug RT-Smart
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
RT-Thread/rt-thread#11717 · 2 comments ·
Maintainers usually reply within 1 day
-
Arch: RISC-V BSP BSP: HPMicro bug
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
RT-Thread/rt-thread#11687 · 3 comments ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
RT-Thread/rt-thread#11472 · 2 comments ·
Maintainers usually reply within 1 day
All issues in RT-Thread/rt-thread
Similar issues
-
v9.6.0: CMake incorrectly enforces presence of libevdevPossibly taken A pull request linked to this issue is open or already merged. Open
Difficulty 2/5 1-3 hours Newbie friendliness 67/100
Maintainers usually reply within 1 day
-
IoTSDK
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
Azure/azure-iot-sdk-c#2776 ·
Maintainers usually reply within 2 days
-
[Bug] Unhandled ValueError terminates watchdog thread when GISRC value contains multiple colonsOpenbug
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
contiki-ng/contiki-ng#3289 ·
Maintainers usually reply within 3 days
-
area:docs help wanted type:enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 1 day