bellard / quickjs

Public repository of the QuickJS Javascript Engine.
https://bellard.org/quickjs
Other
8.35k stars 867 forks source link

dynamic-stack-buffer-overflow in js_os_chdir #281

Open renatahodovan opened 5 months ago

renatahodovan commented 5 months ago

Version: 3b45d15 Command: ./qjs --std test.js Build: CONFIG_ASAN=y make qjs Test:

os.chdir()

Backtrace:

=================================================================
==1798447==ERROR: AddressSanitizer: dynamic-stack-buffer-overflow on address 0x7fffffffcb50 at pc 0x5555557531aa bp 0x7fffffffbec0 sp 0x7fffffffbeb0
READ of size 16 at 0x7fffffffcb50 thread T0
    #0 0x5555557531a9 in js_os_chdir quickjs/quickjs-libc.c:2448
    #1 0x55555567e77e in js_call_c_function quickjs/quickjs.c:16014
    #2 0x5555555b7ef3 in JS_CallInternal quickjs/quickjs.c:16209
    #3 0x5555555b96d7 in JS_CallInternal quickjs/quickjs.c:16616
    #4 0x5555555d74f9 in JS_CallFree quickjs/quickjs.c:18695
    #5 0x55555572b235 in JS_EvalFunctionInternal quickjs/quickjs.c:34351
    #6 0x55555572ec1a in __JS_EvalInternal quickjs/quickjs.c:34486
    #7 0x5555557218bd in JS_EvalInternal quickjs/quickjs.c:34504
    #8 0x5555557218bd in JS_EvalThis quickjs/quickjs.c:34535
    #9 0x5555557218bd in JS_Eval quickjs/quickjs.c:34543
    #10 0x55555558a761 in eval_buf quickjs/qjs.c:71
    #11 0x55555558a957 in eval_file quickjs/qjs.c:103
    #12 0x555555589875 in main quickjs/qjs.c:516
    #13 0x7ffff7608d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #14 0x7ffff7608e3f in __libc_start_main_impl ../csu/libc-start.c:392
    #15 0x555555589e24 in _start (quickjs/qjs+0x35e24)

Address 0x7fffffffcb50 is located in stack of thread T0 at offset 2112 in frame
    #0 0x5555555b61df in JS_CallInternal quickjs/quickjs.c:16139

  This frame has 27 object(s):
    [32, 36) 'len' (line 16780)
    [48, 52) 'done' (line 15358)
    [64, 68) 'done' (line 15404)
    [80, 88) 'pr' (line 7351)
    [112, 120) 'pr' (line 7293)
    [144, 160) 'op1' (line 18143)
    [176, 192) 'op1' (line 18168)
    [208, 224) 'func_obj' (line 16136)
    [240, 256) 'this_obj' (line 16137)
    [272, 288) 'new_target' (line 16137)
    [304, 384) 'sf_s' (line 16144)
    [416, 448) 'ops' (line 17933)
    [480, 512) 'resolving_funcs' (line 28629)
    [544, 608) 'args' (line 28630)
    [640, 704) 'buf' (line 6707)
    [736, 800) 'buf' (line 6715)
    [832, 896) 'buf' (line 6804)
    [928, 992) 'buf' (line 6804)
    [1024, 1088) 'buf' (line 6797)
    [1120, 1184) 'buf' (line 6804)
    [1216, 1280) 'buf' (line 6804)
    [1312, 1376) 'buf' (line 6804)
    [1408, 1472) 'buf' (line 6804)
    [1504, 1568) 'buf' (line 6707)
    [1600, 1664) 'buf' (line 6707)
    [1696, 1760) 'buf' (line 6707)
    [1792, 1856) 'buf' (line 6707) <== Memory access at offset 2112 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: dynamic-stack-buffer-overflow quickjs/quickjs-libc.c:2448 in js_os_chdir
Shadow bytes around the buggy address:
  0x10007fff7910: f2 f2 00 00 00 00 00 00 00 00 f2 f2 f2 f2 00 00
  0x10007fff7920: 00 00 00 00 00 00 f2 f2 f2 f2 00 00 00 00 00 00
  0x10007fff7930: 00 00 f2 f2 f2 f2 00 00 00 00 00 00 00 00 f2 f2
  0x10007fff7940: f2 f2 00 00 00 00 00 00 00 00 f3 f3 f3 f3 00 00
  0x10007fff7950: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x10007fff7960: ca ca ca ca 00 00 00 00 00 00[cb]cb cb cb cb cb
  0x10007fff7970: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007fff7980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007fff7990: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10007fff79a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1
  0x10007fff79b0: f1 f1 04 f2 04 f2 04 f2 00 f2 f2 f2 00 f2 f2 f2
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==1798447==ABORTING

The issue was found by libFuzzer with a Grammarinator-based custom mutator.

chqrlie commented 5 months ago

Thank you for the feedback. I shall fix this promptly