AsyncSRT.dispose()/worker.terminate() causes native heap corruption (reproduces on v1.5.5 and v1.5.6)

オープン
#91 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
48/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
静か
技術スタック
javascript, node.js

調査の方向性

まず spec/async_srt_await_spec.js の close-then-dispose シナリオを再現し、src/async.js の AsyncSRT 実装を読みます。既存の async spec を比較し、その後、worker のシャットダウン前にネイティブソケットの teardown が完了するまで dispose が待機するようにし、close plus dispose のカバレッジを追加します。spec が heap corruption や teardown の失敗なしでパスすれば完了です。

索引モデルが issue の本文から書いたものです。

説明

bug ready-for-maintainer

Summary

AsyncSRT.dispose() (which calls Worker.terminate() under the hood — see src/async.js) causes native heap corruption when called on a worker that has active or recently-closed SRT sockets. This reproduces on both v1.5.5 and v1.5.6 of the bundled libSRT — it is unrelated to the version-bump work in #89/#90.

This code path currently has no test coverage: dispose()/worker.terminate() is never called in spec/async_srt_await_spec.js (it's commented out) and is absent from every other spec file.

Reproduction

In a spec exercising AsyncSRT: create socket(s), close them via the async API, then call dispose() on the AsyncSRT instance (which calls Worker.terminate()) before the process exits.

Observed on Linux (node:20-bookworm, arm64, matching CI's toolchain):

free(): invalid pointer

and, on other runs of the same scenario:

free(): invalid next size (fast)

and one occurrence of a V8 fatal error during worker teardown:

Check failed: node->IsInUse().

All are consistent with a race between Worker.terminate() tearing down the worker thread/its Realm and the native addon's own in-flight close()/socket-teardown state still running inside that same worker thread — i.e. terminate() doesn't wait for the native binding's cleanup to finish before the thread (and its heap) is torn down.

Why this matters

Heap corruption (free(): invalid pointer / invalid next size) is a use-after-free/double-free class bug — exploitable in principle, not just a crash. Any application using AsyncSRT.dispose() for graceful shutdown (a reasonable, expected use of a public API method) can hit this today, independent of which libSRT version is bundled.

Suggested fix direction

Worker.terminate() is inherently abrupt — it doesn't let in-flight work finish. A safer dispose() likely needs to:

  • signal the worker to finish any pending native close()/socket teardown and acknowledge completion (e.g. a message round-trip) before calling worker.terminate(), or
  • avoid terminate() entirely in favor of a graceful shutdown message the worker acts on and then exits on its own.

Suggested test coverage

Un-comment and fix the existing dispose() call in spec/async_srt_await_spec.js, and add explicit close+dispose coverage to the other async spec files, so this path is exercised by CI going forward.


Found incidentally while investigating #89/#90 (libSRT v1.5.6 CVE fix); filed separately since it's unrelated to that work and affects the current release.

主要言語
JavaScript
スター
99
フォーク
35
PR マージ指標
30日以内にマージされた PR はありません

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

Eyevinn/node-srt のほかの issue

Eyevinn/node-srt の issue をすべて見る

似ている issue

JavaScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。