perf_hooks: Histogram.DoImport reads SharedArrayBuffer-backed data without copying (TOCTOU)

未關閉
#67,152 0 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

維護者通常 1 天內回覆

還沒有人認領這個 Issue。

評估

難度
3/5
預估耗時
1-2 天
新手友好度
62/100
Issue 類型
缺陷
描述清晰度
描述清楚
活躍度
活躍
技術堆疊
cpp, javascript
領域
security

研究方向

Read HistogramImpl::DoImport in src/histogram.cc and compare its buffer handling with the SharedArrayBuffer copy in src/node_buffer.cc. Find the existing histogram import tests and check how they cover Uint8Array inputs. Done means SAB-backed input is copied before Histogram::Import parses it, with normal inputs retaining their behavior and tests covering the case.

由索引模型根據 Issue 內容生成。

描述

Summary

HistogramImpl::DoImport in src/histogram.cc accepts a Uint8Array and reads the underlying buffer directly during CBOR parsing. When the Uint8Array is backed by a SharedArrayBuffer, a concurrent Worker thread can mutate the buffer while parsing is in progress, causing a time-of-check/time-of-use (TOCTOU) race.

Affected code

src/histogram.cc — HistogramImpl::DoImport (around line 3202):

Local<Uint8Array> input = args[0].As<Uint8Array>();
auto backing = input->Buffer()->GetBackingStore();
const uint8_t* data =
    static_cast<const uint8_t*>(backing->Data()) + input->ByteOffset();
size_t len = input->ByteLength();
// ← no IsSharedArrayBuffer() check
auto histogram = Histogram::Import(data, len);  // reads data during multi-step CBOR parse

There is no check for input->Buffer()->IsSharedArrayBuffer(). The CBOR parser in Histogram::Import performs multi-step parsing over data without any snapshot or copy.

Scenario

// Worker A — triggers importHistogram with a SAB-backed view
const sab = new SharedArrayBuffer(exportedBytes.length);
const view = new Uint8Array(sab);
view.set(exportedBytes);
// SAB is shared with Worker B via workerData or postMessage
importHistogram(view);  // Worker A starts CBOR parse

// Worker B — running concurrently
const view2 = new Uint8Array(sab);  // same SAB
view2[criticalOffset] = 0xff;       // mutates header field mid-parse

The perf_hooks worker-import pattern in handleMetricsImportWorker-style code already uses this exact shape: the server creates a SAB, copies request data into it, and passes it to a Worker. If the main thread or another Worker modifies the SAB while the Worker is inside importHistogram, the CBOR parser sees inconsistent data.

Existing precedent

src/node_buffer.cc lines 587–592 already handles this case for Buffer.toString():

if (view->Buffer()->IsSharedArrayBuffer()) {
  data_copy = std::make_unique_for_overwrite<char[]>(length);
  memcpy(data_copy.get(), data_ptr + start, length);
  data_ptr = data_copy.get();
  start = 0;
}

Proposed fix

Copy SAB-backed data to a local buffer before passing to Histogram::Import, matching the node_buffer.cc pattern. This eliminates the race without changing behavior for normal (non-SAB) Uint8Array inputs.

Severity

Low. Exploitation requires the caller to intentionally share a SAB with the histogram import thread and mutate it during parsing. This is not remotely triggerable without cooperation from same-process JavaScript. It is a defense-in-depth hardening, not a CVE-eligible vulnerability.

主要語言
JavaScript
星號
123k
分支
39.3k
平均合併
4 天 15 小時
30 天內合併 PR
238

環境準備

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

nodejs/node 的其他 Issue

查看 nodejs/node 的全部 Issue

相似的 Issue

更多 JavaScript Issue

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。