]> git.kaiwu.me - njs.git/commitdiff
Buffer: fix out-of-bounds access in readInt/writeInt with zero byteLength
authorDmitry Volyntsev <xeioex@nginx.com>
Fri, 12 Jun 2026 01:24:28 +0000 (18:24 -0700)
committerDmitry Volyntsev <xeioexception@gmail.com>
Tue, 16 Jun 2026 23:22:57 +0000 (16:22 -0700)
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
src/qjs_buffer.c

index 75b7192bbbc428b39473473bec4ea5c500ec112f..e88d108ce956091da08e93971cc76b629a4de0af 100644 (file)
@@ -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;
         }
     }
index f51fc5a4d9214a05178bdea501a04efca07c2b7c..d7c8204c8393a84be4aad99e669f115221a4256c 100644 (file)
@@ -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");
         }
     }