pcmacdon / jsish

Jsi is a small, C-embeddable javascript interpreter with tightly woven Web and DB support.
https://jsish.org/
MIT License
42 stars 9 forks source link

heap-use-after-free ./jsish/src/jsiValue.c:41:5 in Jsi_DecrRefCount #99

Open Ye0nny opened 9 months ago

Ye0nny commented 9 months ago
Jsish revision

Commit: https://github.com/pcmacdon/jsish/commit/42c694c152f7f4fbee34d5e14be37d6e0d09673f Version: v3.5.0

Build platform

Ubuntu 20.04.5 LTS (Linux 5.4.0-144-generic x86_64)

Build steps
export JSI__SANITIZE=1
make
Test case
testcase

```javascript var e = { set foo ( t ) { n ( 42 ) ; } } ; var r = { set foo ( t ) { }, get bar ( ) { }, get foo ( ) { } } ; var o = { set foo ( t ) { n ( 42 ) ; }, set bar ( t ) { }, get foo ( ) { return 42 ; } } ; var a = { set foo ( t ) { }, ownKeys : Object. getOwnPropertyDescriptors, set : function ( func0, r, t, a ) { return true ; } } ; Object. setPrototypeOf ( Object. create ( e ), Object. create ( o ) ) ; Object. setPrototypeOf ( e, r ) ; var var0 = { set foo ( t ) { } } ; var var1 = t. set ; t. foo = 1 ; var var0 ; r = a ; t = new Proxy ( e, r ) ; e = Object. defineProperty ( e, " attr ", { configurable : false, writable : true, value : " foo " } ) ; assert ( Reflect. set ( t, " foo " ). toString ( ) ) ; assertEq ( Reflect. set ( t ( e ), " attr ", 1 ) ) ; ```

// poc.js
var e = {};
var o = {};
Object. setPrototypeOf ( Object. create ( e ), Object. create ( o ) ) ;
Execution steps & Output
$ ./jsish/jsish poc.js
=================================================================
==3944008==ERROR: AddressSanitizer: heap-use-after-free on address 0x603000006b80 at pc 0x0000004ed9dd bp 0x7ffd7aefd1d0 sp 0x7ffd7aefd1c8
READ of size 4 at 0x603000006b80 thread T0
    #0 0x4ed9dc in Jsi_DecrRefCount ./jsish/src/jsiValue.c:41:5
    #1 0x604e69 in Jsi_ObjFree ./jsish/src/jsiObj.c:362:9
    #2 0x606b21 in Jsi_ObjDecrRefCount ./jsish/src/jsiObj.c:443:9
    #3 0x4edbf0 in ValueFree ./jsish/src/jsiValue.c:178:13
    #4 0x4edbf0 in Jsi_ValueFree ./jsish/src/jsiValue.c:199:5
    #5 0x4ed981 in Jsi_DecrRefCount ./jsish/src/jsiValue.c:52:9
    #6 0x604ce4 in Jsi_ObjFree ./jsish/src/jsiObj.c:356:17
    #7 0x606b21 in Jsi_ObjDecrRefCount ./jsish/src/jsiObj.c:443:9
    #8 0x4edbf0 in ValueFree ./jsish/src/jsiValue.c:178:13
    #9 0x4edbf0 in Jsi_ValueFree ./jsish/src/jsiValue.c:199:5
    #10 0x4ed981 in Jsi_DecrRefCount ./jsish/src/jsiValue.c:52:9
    #11 0x766e61 in jsiEvalFunction ./jsish/src/jsiEval.c:854:5
    #12 0x766e61 in jsiEvalCodeSub ./jsish/src/jsiEval.c:1269:25
    #13 0x780f26 in jsi_evalcode ./jsish/src/jsiEval.c:2227:10
    #14 0x78396f in jsi_evalStrFile ./jsish/src/jsiEval.c
    #15 0x74a726 in Jsi_EvalFile ./jsish/src/jsiEval.c:2729:12
    #16 0x5176d5 in Jsi_Main ./jsish/src/jsiInterp.c:936:18
    #17 0xdefaa3 in jsi_main ./jsish/src/main.c:47:26
    #18 0x7f4ae1a4d082 in __libc_start_main /build/glibc-wuryBv/glibc-2.31/csu/../csu/libc-start.c:308:16
    #19 0x42c9bd in _start (./jsish/jsish+0x42c9bd)

0x603000006b80 is located 0 bytes inside of 32-byte region [0x603000006b80,0x603000006ba0)
freed by thread T0 here:
    #0 0x4a4e7d in free (./jsish/jsish+0x4a4e7d)
    #1 0x4ed981 in Jsi_DecrRefCount ./jsish/src/jsiValue.c:52:9

previously allocated by thread T0 here:
    #0 0x4a5272 in calloc (./jsish/jsish+0x4a5272)
    #1 0x53611e in Jsi_Calloc ./jsish/src/jsiUtils.c:57:15

SUMMARY: AddressSanitizer: heap-use-after-free ./jsish/src/jsiValue.c:41:5 in Jsi_DecrRefCount
Shadow bytes around the buggy address:
  0x0c067fff8d20: fa fa 00 00 00 00 fa fa 00 00 00 00 fa fa 00 00
  0x0c067fff8d30: 00 00 fa fa 00 00 00 00 fa fa 00 00 00 00 fa fa
  0x0c067fff8d40: 00 00 00 00 fa fa fd fd fd fd fa fa 00 00 00 00
  0x0c067fff8d50: fa fa fd fd fd fd fa fa fd fd fd fd fa fa 00 00
  0x0c067fff8d60: 00 00 fa fa 00 00 00 00 fa fa fd fd fd fd fa fa
=>0x0c067fff8d70:[fd]fd fd fd fa fa fd fd fd fd fa fa fd fd fd fd
  0x0c067fff8d80: fa fa fd fd fd fd fa fa fd fd fd fd fa fa 00 00
  0x0c067fff8d90: 00 00 fa fa 00 00 00 00 fa fa fd fd fd fd fa fa
  0x0c067fff8da0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8db0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff8dc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
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
  Shadow gap:              cc
==3944008==ABORTING

Credits: @Ye0nny, @EJueon of the seclab-yonsei.

pcmacdon commented 9 months ago

Thanks for the bug reports, but jsish is no longer being developed or supported.

On Fri, Jan 19, 2024 at 7:25 PM Seyeon Jeong @.***> wrote:

Jsish revision

Commit: 42c694c https://github.com/pcmacdon/jsish/commit/42c694c152f7f4fbee34d5e14be37d6e0d09673f Version: v3.5.0 Build platform

Ubuntu 20.04.5 LTS (Linux 5.4.0-144-generic x86_64) Build steps

export JSI__SANITIZE=1 make

Test case testcase

var e = { set foo ( t ) { n ( 42 ) ; } } ; var r = { set foo ( t ) { }, get bar ( ) { }, get foo ( ) { } } ; var o = { set foo ( t ) { n ( 42 ) ; }, set bar ( t ) { }, get foo ( ) { return 42 ; } } ; var a = { set foo ( t ) { }, ownKeys : Object. getOwnPropertyDescriptors, set : function ( func0, r, t, a ) { return true ; } } ; Object. setPrototypeOf ( Object. create ( e ), Object. create ( o ) ) ; Object. setPrototypeOf ( e, r ) ; var var0 = { set foo ( t ) { } } ; var var1 = t. set ; t. foo = 1 ; var var0 ; r = a ; t = new Proxy ( e, r ) ; e = Object. defineProperty ( e, " attr ", { configurable : false, writable : true, value : " foo " } ) ; assert ( Reflect. set ( t, " foo " ). toString ( ) ) ; assertEq ( Reflect. set ( t ( e ), " attr ", 1 ) ) ;

// poc.jsvar e = {};var o = {};Object. setPrototypeOf ( Object. create ( e ), Object. create ( o ) ) ;

Execution steps & Output

$ ./jsish/jsish poc.js

==3944008==ERROR: AddressSanitizer: heap-use-after-free on address 0x603000006b80 at pc 0x0000004ed9dd bp 0x7ffd7aefd1d0 sp 0x7ffd7aefd1c8 READ of size 4 at 0x603000006b80 thread T0

0 0x4ed9dc in Jsi_DecrRefCount ./jsish/src/jsiValue.c:41:5

#1 0x604e69 in Jsi_ObjFree ./jsish/src/jsiObj.c:362:9
#2 0x606b21 in Jsi_ObjDecrRefCount ./jsish/src/jsiObj.c:443:9
#3 0x4edbf0 in ValueFree ./jsish/src/jsiValue.c:178:13
#4 0x4edbf0 in Jsi_ValueFree ./jsish/src/jsiValue.c:199:5
#5 0x4ed981 in Jsi_DecrRefCount ./jsish/src/jsiValue.c:52:9
#6 0x604ce4 in Jsi_ObjFree ./jsish/src/jsiObj.c:356:17
#7 0x606b21 in Jsi_ObjDecrRefCount ./jsish/src/jsiObj.c:443:9
#8 0x4edbf0 in ValueFree ./jsish/src/jsiValue.c:178:13
#9 0x4edbf0 in Jsi_ValueFree ./jsish/src/jsiValue.c:199:5
#10 0x4ed981 in Jsi_DecrRefCount ./jsish/src/jsiValue.c:52:9
#11 0x766e61 in jsiEvalFunction ./jsish/src/jsiEval.c:854:5
#12 0x766e61 in jsiEvalCodeSub ./jsish/src/jsiEval.c:1269:25
#13 0x780f26 in jsi_evalcode ./jsish/src/jsiEval.c:2227:10
#14 0x78396f in jsi_evalStrFile ./jsish/src/jsiEval.c
#15 0x74a726 in Jsi_EvalFile ./jsish/src/jsiEval.c:2729:12
#16 0x5176d5 in Jsi_Main ./jsish/src/jsiInterp.c:936:18
#17 0xdefaa3 in jsi_main ./jsish/src/main.c:47:26
#18 0x7f4ae1a4d082 in __libc_start_main /build/glibc-wuryBv/glibc-2.31/csu/../csu/libc-start.c:308:16
#19 0x42c9bd in _start (./jsish/jsish+0x42c9bd)

0x603000006b80 is located 0 bytes inside of 32-byte region [0x603000006b80,0x603000006ba0) freed by thread T0 here:

0 0x4a4e7d in free (./jsish/jsish+0x4a4e7d)

#1 0x4ed981 in Jsi_DecrRefCount ./jsish/src/jsiValue.c:52:9

previously allocated by thread T0 here:

0 0x4a5272 in calloc (./jsish/jsish+0x4a5272)

#1 0x53611e in Jsi_Calloc ./jsish/src/jsiUtils.c:57:15

SUMMARY: AddressSanitizer: heap-use-after-free ./jsish/src/jsiValue.c:41:5 in Jsi_DecrRefCount Shadow bytes around the buggy address: 0x0c067fff8d20: fa fa 00 00 00 00 fa fa 00 00 00 00 fa fa 00 00 0x0c067fff8d30: 00 00 fa fa 00 00 00 00 fa fa 00 00 00 00 fa fa 0x0c067fff8d40: 00 00 00 00 fa fa fd fd fd fd fa fa 00 00 00 00 0x0c067fff8d50: fa fa fd fd fd fd fa fa fd fd fd fd fa fa 00 00 0x0c067fff8d60: 00 00 fa fa 00 00 00 00 fa fa fd fd fd fd fa fa =>0x0c067fff8d70:[fd]fd fd fd fa fa fd fd fd fd fa fa fd fd fd fd 0x0c067fff8d80: fa fa fd fd fd fd fa fa fd fd fd fd fa fa 00 00 0x0c067fff8d90: 00 00 fa fa 00 00 00 00 fa fa fd fd fd fd fa fa 0x0c067fff8da0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c067fff8db0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c067fff8dc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 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 Shadow gap: cc ==3944008==ABORTING

Credits: @Ye0nny https://github.com/Ye0nny, @EJueon https://github.com/EJueon of the seclab-yonsei.

— Reply to this email directly, view it on GitHub https://github.com/pcmacdon/jsish/issues/99, or unsubscribe https://github.com/notifications/unsubscribe-auth/AE3J7BQWDCLU73B3W7AIB33YPNIMDAVCNFSM6AAAAABCC462SOVHI2DSMVQWIX3LMV43ASLTON2WKOZSGA4TCOJQGUZTGOA . You are receiving this because you are subscribed to this thread.Message ID: @.***>