{"id":30703,"date":"2026-09-30T04:31:04","date_gmt":"2026-09-29T20:31:04","guid":{"rendered":"https:\/\/www.54iter.cn\/?vuln=cve-2026-102720"},"modified":"2026-09-30T04:31:04","modified_gmt":"2026-09-29T20:31:04","slug":"cve-2026-102720","status":"publish","type":"vuln","link":"https:\/\/www.54iter.cn\/?vuln=cve-2026-102720","title":{"rendered":"CVE-2026-102720 &#8211; A DHCP server, or anyone on the LAN who answers a DISCOVER first, can make the client read"},"content":{"rendered":"<p>A DHCP server, or anyone on the LAN who answers a DISCOVER first, can make the client read about a<\/p>\n<p>kilobyte past the end of the received message.<\/p>\n<p>The option walk keeps a pointer and an offset in step, and the only bound check uses the offset:<\/p>\n<p>&#8220;`c<\/p>\n<p>\/* addons\/dhcp\/nxd_dhcp_client.c:7538, 7572 *\/<\/p>\n<p>while (i  length byte *\/<br \/>\n    data += size + 1;      \/* data moves size + 1 more          *\/<br \/>\n    i += size + 1;         \/* i moves only size + 1             *\/<\/p>\n<p>}<\/p>\n<p>&#8220;`<\/p>\n<p>A TLV option occupies size + 2 bytes. `data` is advanced by size + 2 in total, `i` by size + 1, so<\/p>\n<p>the offset falls one byte behind the real read position for every option the walk skips. After<\/p>\n<p>enough skipped options the check `i &lt; length &#8211; 1` still holds while `data` is already past the end<\/p>\n<p>of the message, and the subsequent read of the type and length bytes comes from whatever follows.<\/p>\n<p>A single OFFER carrying a long run of skippable options is enough:<\/p>\n<p>&#8220;`<\/p>\n<p>ERROR: AddressSanitizer: heap-buffer-overflow<\/p>\n<p>READ of size 1 at 0x61b000000794 thread T5<\/p>\n<p>    #0 _nx_dhcp_search_buffer     addons\/dhcp\/nxd_dhcp_client.c:7541<br \/>\n    #1 _nx_dhcp_get_option_value  addons\/dhcp\/nxd_dhcp_client.c:7082<\/p>\n<p>0x61b000000794 is located 164 bytes to the right of 1648-byte region<\/p>\n<p>&#8220;`<\/p>\n<p>A well formed OFFER through the same path is handled normally, the client records the offer and<\/p>\n<p>moves to REQUESTING, so the difference is the option layout rather than the harness.<\/p>\n<p>The read runs in the DHCP client thread while the client is still unconfigured, so it happens on<\/p>\n<p>every boot in reach of a hostile DHCP responder. The values read are used to configure the<\/p>\n<p>interface, which is how the disclosed bytes become observable.<\/p>\n<p>Advance `i` by size + 2, or derive the bound from `data` rather than keeping a second counter.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A DHCP server, or anyone on the LAN who answers a DISCOVER first, can make the client read about a<\/p>\n<p>kilobyte past the end of the received message.<\/p>\n<p>The option walk keeps a pointer and an offset in<\/p>\n","protected":false},"template":"","meta":[],"categories":[],"tags":[],"class_list":["post-30703","vuln","type-vuln","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/vuln\/30703","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/vuln"}],"about":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=\/wp\/v2\/types\/vuln"}],"wp:attachment":[{"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=30703"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=30703"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.54iter.cn\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=30703"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}