JakeChampion / JakeChampion/trafficserver

[audit][plugin-api] TSContCall aborts the whole server on benign lock contention and skips m_event_count bookkeeping

Open
#33 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

area:plugin-api audit severity:medium
Dominant language
C++
Stars
0
Forks
0
Avg merge
8h 2m
Merged PRs (30d)
21

Description

Severity: medium · Category: logic-bug
Location: src/api/InkAPI.cc:3755

What's wrong

TSContCall is the only continuation API with no sdk_assert on contp, and on a failed try-lock of the target continuation's mutex it executes ink_release_assert(0), turning ordinary cross-thread lock contention (e.g. a lua/fetch plugin calling another continuation whose mutex is momentarily held elsewhere) into a full traffic_server crash instead of an error return the plugin could handle. Additionally it invokes handleEvent() directly without the m_event_count increment that APIHook::invoke() (src/api/APIHook.cc:50-53) and TSContSchedule* perform, while INKContInternal::handle_event_count() (InkContInternal.cc:133-141) unconditionally decrements for EVENT_IMMEDIATE/EVENT_INTERVAL/TS_EVENT_HTTP_TXN_CLOSE; a plugin passing TS_EVENT_IMMEDIATE to TSContCall on a TSCont drives m_event_count negative, skewing the m_deletable computation so a later TSContDestroy can free the continuation while an event is still outstanding (use-after-free / 'continuation which is deleted' release assert) or never free it (leak).

Evidence
InkAPI.cc:3755-3763:
TSContCall(TSCont contp, TSEvent event, void *edata) {
  Continuation *c = reinterpret_cast<Continuation *>(contp);
  WEAK_MUTEX_TRY_LOCK(lock, c->mutex, this_ethread());
  if (!lock.is_locked()) {
    ink_release_assert(0);
  }
  return c->handleEvent(static_cast<int>(event), edata);
}
Suggested fix

Add sdk_assert(sdk_sanity_check_iocore_structure(contp)); return an error (or blocking-lock like APIHook::blocking_invoke) instead of ink_release_assert on contention; and when the target is an INKContInternal, pre-increment m_event_count for the events handle_event_count() will decrement.


Filed from an automated multi-lens codebase audit. Full report: CODEBASE_AUDIT.md / audit-report.html on branch claude/codebase-audit-review-9nw7vz.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/api/InkAPI.cc:3755 and compare TSContCall with APIHook::invoke() at src/api/APIHook.cc:50-53 and handle_event_count() in InkContInternal.cc:133-141. Trace lock contention and the EVENT_IMMEDIATE, EVENT_INTERVAL, and TS_EVENT_HTTP_TXN_CLOSE paths. Done means contention no longer aborts the server and m_event_count bookkeeping remains balanced through continuation destruction.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.