From e07124084a246ed40d2221da1e2f3e624e93588f Mon Sep 17 00:00:00 2001 From: Dmitry Volyntsev Date: Thu, 11 Jun 2026 18:24:28 -0700 Subject: [PATCH] Buffer: fix out-of-bounds access in readInt/writeInt with zero byteLength The variable-length readIntLE/UIntLE/BE and writeIntLE/UIntLE/BE only rejected byteLength > 6. byteLength == 0 passed, the bounds check "size + index > byte_length" degenerated to "index > byte_length", and switch (size) fell through to the 6-byte arm, reading or writing 6 bytes past an attacker-chosen offset. Require byteLength in [1, 6] as Node does. --- src/njs_buffer.c | 8 ++++---- src/qjs_buffer.c | 10 ++++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/njs_buffer.c b/src/njs_buffer.c index 75b7192b..e88d108c 100644 --- a/src/njs_buffer.c +++ b/src/njs_buffer.c @@ -1010,8 +1010,8 @@ njs_buffer_prototype_read_int(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } size = (size_t) njs_number(value); - if (njs_slow_path(size > 6)) { - njs_type_error(vm, "\"byteLength\" must be <= 6"); + if (njs_slow_path(size == 0 || size > 6)) { + njs_type_error(vm, "\"byteLength\" must be >= 1 and <= 6"); return NJS_ERROR; } } @@ -1296,8 +1296,8 @@ njs_buffer_prototype_write_int(njs_vm_t *vm, njs_value_t *args, } size = (size_t) njs_number(value); - if (njs_slow_path(size > 6)) { - njs_type_error(vm, "\"byteLength\" must be <= 6"); + if (njs_slow_path(size == 0 || size > 6)) { + njs_type_error(vm, "\"byteLength\" must be >= 1 and <= 6"); return NJS_ERROR; } } diff --git a/src/qjs_buffer.c b/src/qjs_buffer.c index f51fc5a4..d7c8204c 100644 --- a/src/qjs_buffer.c +++ b/src/qjs_buffer.c @@ -1178,8 +1178,9 @@ qjs_buffer_prototype_read_int(JSContext *ctx, JSValueConst this_val, return JS_EXCEPTION; } - if (size > 6) { - return JS_ThrowRangeError(ctx, "\"byteLength\" must be <= 6"); + if (size == 0 || size > 6) { + return JS_ThrowRangeError(ctx, + "\"byteLength\" must be >= 1 and <= 6"); } } @@ -1615,8 +1616,9 @@ qjs_buffer_prototype_write_int(JSContext *ctx, JSValueConst this_val, return JS_EXCEPTION; } - if (size > 6) { - return JS_ThrowRangeError(ctx, "\"byteLength\" must be <= 6"); + if (size == 0 || size > 6) { + return JS_ThrowRangeError(ctx, + "\"byteLength\" must be >= 1 and <= 6"); } } -- 2.47.3