Commit 2e07f25
committed
fix: bound DNS compression-pointer chain depth in DNSIncoming
Closes #1713.
A crafted mDNS packet can chain thousands of forward compression
pointers into a single ~3 kB datagram. ``DNSIncoming._decode_labels_at_offset``
recurses once per pointer it follows (RFC 1035 §4.1.4 name compression),
so a deep chain blows through CPython's default recursion limit
(``sys.getrecursionlimit() == 1000``). ``RecursionError`` was *not*
in ``DECODE_EXCEPTIONS``, so it escaped ``DNSIncoming.__init__`` and
bubbled up to asyncio's default exception handler — turning a single
small multicast packet from any host on the local link (a guest on
the same Wi-Fi, a compromised IoT device, a container on a shared
bridge) into sustained CPU burn (each crash unwinds ~1000 frames +
the asyncio exception machinery) and debug-log flooding. Home
Assistant deployments on Raspberry-Pi-class hardware are the
canonical victim.
``seen_pointers`` already blocked cycles and ``MAX_DNS_LABELS = 128``
already capped the *number of labels*, but nothing capped the *chain
length of unique forward pointers*. A ``_MAX_MSG_ABSOLUTE`` (8966 B)
packet can carry ~4000 2-byte pointers, each pointing to the next.
Thread an explicit ``depth`` counter through ``_decode_labels_at_offset``
and raise ``IncomingDecodeError`` when it exceeds ``MAX_DNS_LABELS``
— same bound as the existing label cap, so no new constant. Belt-and-
braces, add ``RecursionError`` to ``DECODE_EXCEPTIONS`` so any future
regression is contained as an invalid packet rather than logged by
asyncio's default handler.
``incoming.pxd`` updated in the same commit so the Cython build picks
up the new ``unsigned int depth`` parameter. ``cython -a`` confirms
the depth check and ``depth + 1`` recursive-call argument both
compile to score-0 (pure C) — direct ``unsigned int`` compare and a
C add — with no Python interaction added to the hot path. Function
entry score is unchanged (score-11, same boilerplate). Wall-clock
smoke test on a typical compressed mDNS response (best-of-10 over
50k iters, REQUIRE_CYTHON=1): 1237.2 ns/parse pre-fix vs 1234.1 ns/parse
post-fix — within noise.
CWE-674 (Uncontrolled Recursion). LAN-local attack surface only.1 parent 64d143d commit 2e07f25
3 files changed
Lines changed: 33 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
83 | 83 | | |
84 | 84 | | |
85 | 85 | | |
86 | | - | |
| 86 | + | |
87 | 87 | | |
88 | 88 | | |
89 | 89 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
60 | 60 | | |
61 | 61 | | |
62 | 62 | | |
63 | | - | |
| 63 | + | |
64 | 64 | | |
65 | 65 | | |
66 | 66 | | |
| |||
409 | 409 | | |
410 | 410 | | |
411 | 411 | | |
412 | | - | |
| 412 | + | |
413 | 413 | | |
414 | 414 | | |
415 | 415 | | |
| |||
418 | 418 | | |
419 | 419 | | |
420 | 420 | | |
421 | | - | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
422 | 424 | | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
423 | 429 | | |
424 | 430 | | |
425 | 431 | | |
| |||
457 | 463 | | |
458 | 464 | | |
459 | 465 | | |
460 | | - | |
| 466 | + | |
461 | 467 | | |
462 | 468 | | |
463 | 469 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1011 | 1011 | | |
1012 | 1012 | | |
1013 | 1013 | | |
| 1014 | + | |
| 1015 | + | |
| 1016 | + | |
| 1017 | + | |
| 1018 | + | |
| 1019 | + | |
| 1020 | + | |
| 1021 | + | |
| 1022 | + | |
| 1023 | + | |
| 1024 | + | |
| 1025 | + | |
| 1026 | + | |
| 1027 | + | |
| 1028 | + | |
| 1029 | + | |
| 1030 | + | |
| 1031 | + | |
| 1032 | + | |
| 1033 | + | |
| 1034 | + | |
| 1035 | + | |
1014 | 1036 | | |
1015 | 1037 | | |
1016 | 1038 | | |
| |||
0 commit comments