Skip to content

Commit 41f9937

Browse files
committed
zlib: fix use-after-free when reset() is called during write
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
1 parent f08e2e0 commit 41f9937

File tree

2 files changed

+29
-0
lines changed

2 files changed

+29
-0
lines changed

src/node_zlib.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,12 @@ class CompressionStream : public AsyncWrap,
644644
CompressionStream* wrap;
645645
ASSIGN_OR_RETURN_UNWRAP(&wrap, args.This());
646646

647+
if (wrap->write_in_progress_) {
648+
wrap->env()->ThrowError(
649+
"Cannot reset zlib stream while a write is in progress");
650+
return;
651+
}
652+
647653
AllocScope alloc_scope(wrap);
648654
const CompressionError err = wrap->context()->ResetStream();
649655
if (err.IsError())
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const { createBrotliCompress, createDeflate } = require('zlib');
5+
6+
// Tests that calling .reset() while an async write is in progress
7+
// throws an error instead of causing a use-after-free.
8+
9+
for (const factory of [createBrotliCompress, createDeflate]) {
10+
const stream = factory();
11+
const input = Buffer.alloc(1024, 0x41);
12+
13+
stream.write(input, common.mustCall());
14+
stream.on('error', common.mustNotCall());
15+
16+
// The write has been dispatched to the thread pool.
17+
// Calling reset while write is in progress must throw.
18+
assert.throws(() => {
19+
stream._handle.reset();
20+
}, {
21+
message: 'Cannot reset zlib stream while a write is in progress',
22+
});
23+
}

0 commit comments

Comments
 (0)