The Reset() method did not check the write_in_progress_ flag before resetting the compression stream. This allowed reset() to free the compression library's internal state while a worker thread was still using it during an async write, causing a use-after-free. Add a write_in_progress_ guard to Reset() that throws an error if a write is in progress, matching the existing pattern used by Close() and Write(). PR-URL: TODO Refs: https://hackerone.com/reports/3609132 PR-URL: https://github.com/nodejs/node/pull/62325 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
23 lines
746 B
JavaScript
23 lines
746 B
JavaScript
'use strict';
|
|
const common = require('../common');
|
|
const assert = require('assert');
|
|
const { createBrotliCompress, createDeflate } = require('zlib');
|
|
|
|
// Tests that calling .reset() while an async write is in progress
|
|
// throws an error instead of causing a use-after-free.
|
|
|
|
for (const factory of [createBrotliCompress, createDeflate]) {
|
|
const stream = factory();
|
|
const input = Buffer.alloc(1024, 0x41);
|
|
|
|
stream.write(input, common.mustCall());
|
|
stream.on('error', common.mustNotCall());
|
|
|
|
// The write has been dispatched to the thread pool.
|
|
// Calling reset while write is in progress must throw.
|
|
assert.throws(() => {
|
|
stream._handle.reset();
|
|
}, {
|
|
message: 'Cannot reset zlib stream while a write is in progress',
|
|
});
|
|
}
|