njs icon indicating copy to clipboard operation
njs copied to clipboard

SEGV in njs_scope_valid_value

Open Q1IQ opened this issue 3 years ago • 0 comments

Environment

OS      : Linux ubuntu 5.11.10 #1 SMP Sat Oct 30 23:40:08 CST 2021 x86_64 x86_64 x86_64 GNU/Linux
Commit  : 04f59f9defeeb618260e620bb11466741c0e41e5
Version : 0.7.4
Build   : 
          NJS_CFLAGS="$NJS_CFLAGS -fsanitize=address"
          NJS_CFLAGS="$NJS_CFLAGS -fno-omit-frame-pointer"

Proof of concept

function main() {
  async function a0(a1, a2) {
    var a4 = await Uint16Array;
    var a6 = [-0.0, -0.0];
    function a7(a8, a9, a10, ...a11) {
      async function a12(a13, a14) {}
      var a15 = a12(a6);
    }
    var a16 = a7();
    function a17(a18, a19) {
      a7 = a18;
    }
  }
  var a20 = a0();
}
main();

Stack dump

Program received signal SIGSEGV, Segmentation fault.
njs_scope_valid_value (index=19, vm=0x55555561a4e0) at src/njs_scope.h:86
86	    if (!njs_is_valid(value)) {
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
──────────────────────────────────────────────────────────────[ REGISTERS ]──────────────────────────────────────────────────────────────
 RAX  0x5555556d9ed8 ◂— 0x7
 RBX  0x55555561a4e0 ◂— 0x608b3d9d00160111
 RCX  0x5555556d8c48 ◂— 0x0
 RDX  0x0
 RDI  0x5555555d60e0 (njs_value_undefined) ◂— 0x1
 RSI  0x13
 R8   0x0
 R9   0x0
 R10  0x555555635a20 —▸ 0x55555561a458 ◂— 0x555555635a20 /* ' ZcUUU' */
 R11  0x5555556cd180 —▸ 0x55555561fd50 ◂— 0x2
 R12  0x0
 R13  0x13
 R14  0x0
 R15  0x5555555d65f4 ◂— 0xfff978a3fff9781f
 RBP  0x5555556d6bb8 ◂— 0x5a5a5a5a5a5a0300
 RSP  0x7fffffffc900 ◂— 0x2000
 RIP  0x55555556de45 (njs_vmcode_interpreter+7195) ◂— cmp    byte ptr [rdx], 7
───────────────────────────────────────────────────────────────[ DISASM ]────────────────────────────────────────────────────────────────
 ► 0x55555556de45 <njs_vmcode_interpreter+7195>    cmp    byte ptr [rdx], 7
   0x55555556de48 <njs_vmcode_interpreter+7198>    je     njs_vmcode_interpreter+7217                <njs_vmcode_interpreter+7217>
    ↓
   0x55555556de5b <njs_vmcode_interpreter+7217>    and    esi, 0xf800000f
   0x55555556de61 <njs_vmcode_interpreter+7223>    cmp    esi, 1
   0x55555556de64 <njs_vmcode_interpreter+7226>    jbe    njs_vmcode_interpreter+7244                <njs_vmcode_interpreter+7244>
    ↓
   0x55555556de76 <njs_vmcode_interpreter+7244>    lea    rcx, [rip + 0x684d3]
   0x55555556de7d <njs_vmcode_interpreter+7251>    mov    edx, 0x20
   0x55555556de82 <njs_vmcode_interpreter+7256>    mov    rsi, rbx
   0x55555556de85 <njs_vmcode_interpreter+7259>    mov    rdi, rbx
   0x55555556de88 <njs_vmcode_interpreter+7262>    mov    eax, 0
   0x55555556de8d <njs_vmcode_interpreter+7267>    call   njs_error_fmt_new                <njs_error_fmt_new>
────────────────────────────────────────────────────────────[ SOURCE (CODE) ]────────────────────────────────────────────────────────────
In file: /home/q1iq/Documents/crashtest/04f59f9/njs/src/njs_scope.h
   81 {
   82     njs_value_t  *value;
   83
   84     value = njs_scope_value(vm, index);
   85
 ► 86     if (!njs_is_valid(value)) {
   87         if (njs_scope_index_var(index) <= NJS_VARIABLE_LET) {
   88             njs_reference_error(vm, "cannot access variable "
   89                                     "before initialization");
   90             return NULL;
   91         }
────────────────────────────────────────────────────────────────[ STACK ]────────────────────────────────────────────────────────────────
00:0000│ rsp 0x7fffffffc900 ◂— 0x2000
01:0008│     0x7fffffffc908 ◂— 0x0
02:0010│     0x7fffffffc910 ◂— 0x0
03:0018│     0x7fffffffc918 ◂— 0x201
04:0020│     0x7fffffffc920 ◂— 0x70 /* 'p' */
05:0028│     0x7fffffffc928 —▸ 0x7ffff79a3c83 (_int_malloc+531) ◂— jmp    0x7ffff79a3e9d
06:0030│     0x7fffffffc930 ◂— 0x1
07:0038│     0x7fffffffc938 ◂— 0x0
──────────────────────────────────────────────────────────────[ BACKTRACE ]──────────────────────────────────────────────────────────────
 ► f 0   0x55555556de45 njs_vmcode_interpreter+7195
   f 1   0x55555556de45 njs_vmcode_interpreter+7195
   f 2   0x5555555893a1 njs_function_lambda_call+417
   f 3   0x5555555893f9 njs_function_frame_invoke+58
   f 4   0x55555556e763 njs_vmcode_interpreter+9529
   f 5   0x5555555bace4 njs_await_fulfilled+175
   f 6   0x555555588d76 njs_function_native_call+49
   f 7   0x555555589400 njs_function_frame_invoke+65
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
pwndbg> bt
#0  njs_scope_valid_value (index=19, vm=0x55555561a4e0) at src/njs_scope.h:86
#1  njs_vmcode_interpreter (vm=vm@entry=0x55555561a4e0, pc=0x5555556d6bb8 "", promise_cap=promise_cap@entry=0x0, async_ctx=async_ctx@entry=0x0) at src/njs_vmcode.c:648
#2  0x00005555555893a1 in njs_function_lambda_call (vm=vm@entry=0x55555561a4e0, promise_cap=promise_cap@entry=0x0, async_ctx=async_ctx@entry=0x0) at src/njs_function.c:693
#3  0x00005555555893f9 in njs_function_frame_invoke (vm=vm@entry=0x55555561a4e0, retval=<optimized out>) at src/njs_function.c:769
#4  0x000055555556e763 in njs_vmcode_interpreter (vm=vm@entry=0x55555561a4e0, pc=0x5555556d7510 "\r\002", promise_cap=0x5555556cee00, async_ctx=async_ctx@entry=0x5555556d8680) at src/njs_vmcode.c:799
#5  0x00005555555bace4 in njs_await_fulfilled (vm=0x55555561a4e0, args=<optimized out>, nargs=<optimized out>, unused=<optimized out>) at src/njs_async.c:91
#6  0x0000555555588d76 in njs_function_native_call (vm=0x55555561a4e0) at src/njs_function.c:728
#7  0x0000555555589400 in njs_function_frame_invoke (vm=vm@entry=0x55555561a4e0, retval=retval@entry=0x7fffffffce40) at src/njs_function.c:766
#8  0x000055555558944b in njs_function_call2 (vm=vm@entry=0x55555561a4e0, function=<optimized out>, this=<optimized out>, args=<optimized out>, nargs=nargs@entry=1, retval=retval@entry=0x7fffffffce90, ctor=0) at src/njs_function.c:592
#9  0x00005555555b5fff in njs_function_call (retval=0x7fffffffce90, nargs=1, args=<optimized out>, this=<optimized out>, function=<optimized out>, vm=0x55555561a4e0) at src/njs_function.h:178
#10 njs_promise_reaction_job (vm=0x55555561a4e0, args=<optimized out>, nargs=<optimized out>, unused=<optimized out>) at src/njs_promise.c:1171
#11 0x0000555555588d76 in njs_function_native_call (vm=0x55555561a4e0) at src/njs_function.c:728
#12 0x0000555555589400 in njs_function_frame_invoke (vm=vm@entry=0x55555561a4e0, retval=retval@entry=0x55555561a4e0) at src/njs_function.c:766
#13 0x000055555556a9e3 in njs_vm_invoke (vm=vm@entry=0x55555561a4e0, function=<optimized out>, args=<optimized out>, nargs=<optimized out>, retval=retval@entry=0x55555561a4e0) at src/njs_vm.c:428
#14 0x000055555556aa14 in njs_vm_call (vm=vm@entry=0x55555561a4e0, function=<optimized out>, args=<optimized out>, nargs=<optimized out>) at src/njs_vm.c:412
#15 0x000055555556b269 in njs_vm_handle_events (vm=0x55555561a4e0) at src/njs_vm.c:572
#16 njs_vm_run (vm=0x55555561a4e0) at src/njs_vm.c:532
#17 0x0000555555565131 in njs_process_script (vm=0x55555561a4e0, opts=0x7fffffffe120, runtime=0x555555619940 <njs_console>, script=<optimized out>) at src/njs_shell.c:924
#18 0x0000555555565548 in njs_process_file (opts=0x7fffffffe120, vm_options=0x7fffffffe160) at src/njs_shell.c:619
#19 0x0000555555565b78 in main (argc=argc@entry=2, argv=argv@entry=0x7fffffffe2d8) at src/njs_shell.c:303
#20 0x00007ffff7930083 in __libc_start_main (main=0x555555565564 <main>, argc=2, argv=0x7fffffffe2d8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe2c8) at ../csu/libc-start.c:308
#21 0x000055555556436e in _start ()

Credit

Q1IQ(@Q1IQ)

Q1IQ avatar Jun 02 '22 09:06 Q1IQ