JakeChampion / JakeChampion/trafficserver
[10.2][net] manage_active_queue/manage_keep_alive_queue cache a next pointer across _close_ne() callbacks that can free queue entries
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 0
- Forks
- 0
- Avg merge
- 8h 2m
- Merged PRs (30d)
- 21
Description
Branch: 10.2.x (10.2.1, commit 31f1f2f3b) · Severity: medium · category: use-after-free (latent)
Location: src/iocore/net/NetHandler.cc:428 (manage_active_queue) and :482 (manage_keep_alive_queue)
What's wrong
Both loops cache ne_next = ne->active_queue_link.next before calling _close_ne(ne, ...). _close_ne() invokes ne->callback(VC_EVENT_*TIMEOUT) → the state machine, which (while the NetHandler mutex is held) can synchronously do_io_close() a different same-thread queued VC; that close runs free_netevent → remove_from_active_queue/remove_from_keep_alive_queue, freeing that VC. If the freed VC is the cached ne_next, the next iteration dereferences freed memory.
InactivityCop::check_inactivity deliberately avoids this with the cop_list.pop() pattern ("Use pop() to catch any closes caused by callbacks", UnixNet.cc:91) — the list stays authoritative because free_netevent removes from cop_list. These two queue walks were not converted.
Why this is a tracked issue, not a PR (yet)
A correct fix needs to mirror the pop-style traversal (re-derive from the authoritative queue rather than a cached raw pointer), which is a non-trivial rework of a hot path that runs under connection-pressure. It should be done with a targeted stress/ASAN test, which isn't feasible in the audit environment. Filing for a maintainer to take with proper testing. Reachable only when a timeout callback closes a different same-thread queued VC (e.g. HTTP/2 or cross-session teardown).
Suggested direction
Convert both loops to the cop_list-style pattern: pop/remove from the queue head and process, re-queuing entries that are kept, so a callback-driven free of any other entry can never leave a dangling iterator; or snapshot into a refcounted list before invoking callbacks.
From an automated multi-lens audit of the 10.2.x branch. Full report on branch claude/codebase-audit-review-9nw7vz (CODEBASE_AUDIT_10.2.md).
Contributor 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.
Research direction
Start in src/iocore/net/NetHandler.cc at manage_active_queue and manage_keep_alive_queue, then compare their traversal with the pop-style pattern in UnixNet.cc:91 and InactivityCop::check_inactivity. Rework the queue walk so callback-driven closes cannot leave a dangling next entry, and verify it with a targeted stress/ASAN test covering same-thread queued VC closures.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100