Skip to content

TSHttpSsnReenable can resume a session on the wrong ET_NET thread #13744

Description

@moonchen

TSHttpSsnReenable() can resume a session on the wrong network thread. Its fast path checks that the caller is an ET_NET thread, but does not check that it is the session's assigned thread.

Trigger

  1. A session-start hook pauses a session on its owner thread A.
  2. A plugin later calls TSHttpSsnReenable() from another network thread B.
  3. B acquires the session mutex. ATS immediately calls the session handler on B, without returning to A.
  4. The next session hook runs on B.

A callback from TS_THREAD_POOL_TASK does not trigger this branch: that path already schedules back to the session's owner. The problem is a call from a different network thread.

Reproduction

Use at least two network threads and register two TS_HTTP_SSN_START_HOOK callbacks:

  1. The first records thread A and returns without reenabling the session.
  2. Use TSContScheduleOnThread() to call TSHttpSsnReenable() on B after the first hook returns.
  3. Record the executing thread in the second hook.

Observed on an ATS 11.0.0 debug build; addresses are replaced with A/B:

session first owner=A other=B
session resume owner=A current=B
session second owner=A current=B wrong_thread=1

Confirmed: the second session hook runs on the wrong thread. No ATS core changes were needed. The probe then returns to A before completing session startup; it does not reproduce an HTTP/2 crash.

The same API branch exists in 10.1.2, but that version was not run.

Agreed fix direction

After discussing this with community members, we agreed that work protected by a NetHandler mutex should run on that NetHandler's owning network thread. Acquiring a mutex on another thread does not establish connection ownership.

  • Caller is on another thread: compare against the session's exact affinity thread and schedule the callback there with the required locks. This applies even when the caller is another ET_NET thread.
  • Caller is already on the owner: preserve synchronous execution with the required locks and the existing lock-failure fallback.
  • Task-thread callers remain supported: retain the existing return to the session's owner from TS_THREAD_POOL_TASK.

TSHttpTxnReenable() already follows the exact-affinity approach. The preferred fix is to enforce it at the session reenable entry point, before session processing can run on the wrong thread. The related NetHandler mutex audit is described in #13743.

Impact

After the hooks finish, session startup runs synchronously. For HTTP/2, startup can immediately process buffered input. This provides a potential route into connection processing on the wrong thread; that consequence was traced in source, not reproduced as a crash. We have not confirmed that this path caused #13358.

Source references and related issues

Found while investigating #13358 and #13362. We have not identified a plugin in that deployment that triggers this path. The shipped callers examined reenable synchronously. Certifier uses TSVConnReenable(), covered separately in #13743.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions