-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Vulnerability description:
Running qjs with the “-m” option on a crafted input file causes an internal assertion failure in gc_decref_child (p->ref_count > 0) and the program terminates with SIGABRT.
Steps to Reproduce:
The PoC attachment contains the input file that triggers the crash:
COMMAND LINE: ./qjs -m Assertion_Failure
Expected behavior
qjs should handle malformed or adversarial scripts by reporting a script error or exiting cleanly, rather than triggering an internal GC assertion and aborting.
version:
Git master branch
commit: e5fd391
OS and version:
Ubuntu 18.04.6 LTS
GDB output excerpt:
Starting program: /root/DriveSched/benchmarks/quickjs/qjs/qjs -m /tmp/PoC/qjs/3_m/979ac40f6ca100d03c2ffa726ed4a205.0001ce29.honggfuzz.cov
warning: Error disabling address space randomization: Operation not permitted
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
qjs: quickjs.c:6273: void gc_decref_child(JSRuntime *, JSGCObjectHeader *): Assertion `p->ref_count > 0' failed.
Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1 0x00007ffff6e367f1 in __GI_abort () at abort.c:79
#2 0x00007ffff6e263fa in __assert_fail_base (fmt=0x7ffff6fad6c0 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x6fa571 "p->ref_count > 0",
file=file@entry=0x6f9acd "quickjs.c", line=line@entry=6273, function=function@entry=0x6fa582 "void gc_decref_child(JSRuntime *, JSGCObjectHeader *)") at assert.c:92
#3 0x00007ffff6e26472 in __GI___assert_fail (assertion=0x6fa571 "p->ref_count > 0", file=0x6f9acd "quickjs.c", line=6273,
function=0x6fa582 "void gc_decref_child(JSRuntime *, JSGCObjectHeader *)") at assert.c:101
#4 0x00000000004e5fcc in gc_decref_child (rt=rt@entry=0xa2ce360, p=p@entry=0xa31b2c0) at quickjs.c:6273
#5 0x00000000004d4b9c in JS_MarkValue (rt=0xa2ce360, val=..., mark_func=0x4e5e60 <gc_decref_child>) at quickjs.c:6144
#6 js_bytecode_function_mark (rt=rt@entry=0xa2ce360, val=..., mark_func=mark_func@entry=0x4e5e60 <gc_decref_child>) at quickjs.c:5869
#7 0x00000000004e5bc6 in mark_children (rt=rt@entry=0xa2ce360, gp=gp@entry=0xa3108a0, mark_func=0x7ffff6e34e87 <__GI_raise+199>) at quickjs.c:6193
#8 0x0000000000455a82 in gc_decref (rt=0xa2ce360) at quickjs.c:6294
#9 JS_RunGCInternal (rt=0xa2ce360, remove_weak_objects=1) at quickjs.c:6410
#10 JS_RunGC (rt=0xa2ce360) at quickjs.c:6421
#11 js_trigger_gc (rt=0xa2ce360, size=72) at quickjs.c:1368
#12 JS_NewObjectFromShape (ctx=ctx@entry=0xa2d3250, sh=sh@entry=0xa308ec0, class_id=class_id@entry=1, props=props@entry=0x0) at quickjs.c:5203
#13 0x00000000004eccec in JS_NewObjectProtoClassAlloc (ctx=0xa2d3250, class_id=1, n_alloc_props=3, proto_val=...) at quickjs.c:5365
#14 JS_NewObjectProtoList (ctx=0xa2d3250, fields=0x6f52f0 <js_json_funcs>, n_fields=3, proto=...) at quickjs.c:38939
#15 JS_InstantiateFunctionListItem2 (ctx=ctx@entry=0xa2d3250, p=p@entry=0xa2d3fb0, atom=atom@entry=169, opaque=opaque@entry=0x6f52d0 <js_json_obj>) at quickjs.c:38969
#16 0x000000000046638e in JS_AutoInitProperty (ctx=ctx@entry=0xa2d3250, p=0x7fffffffd6b0, p@entry=0xa2d3fb0, prop=0, pr=pr@entry=0xa2e81b0, prs=prs@entry=0xa2e88d0)
at quickjs.c:7766
#17 0x00000000005300c8 in js_closure_global_var (ctx=0x2, ctx@entry=0xa2d3250, cv=0x0, cv@entry=0xa31b4fc) at quickjs.c:16864
#18 0x000000000052c757 in js_closure2 (ctx=ctx@entry=0xa2d3250, func_obj=..., b=b@entry=0xa31b2c0, cur_var_refs=cur_var_refs@entry=0x0, sf=sf@entry=0x0, is_eval=1, m=0xa2e9000)
at quickjs.c:16926
#19 0x000000000054e23a in js_create_module_bytecode_function (ctx=0xa2d3250, m=0xa2e9000) at quickjs.c:29959
#20 js_create_module_function (ctx=ctx@entry=0xa2d3250, m=m@entry=0xa2e9000) at quickjs.c:29993
#21 0x00000000004b0d42 in JS_EvalFunctionInternal (ctx=ctx@entry=0xa2d3250, fun_obj=..., this_obj=..., var_refs=var_refs@entry=0x0, sf=0x0) at quickjs.c:36550
#22 0x00000000004b0a9a in JS_EvalFunction (ctx=ctx@entry=0xa2d3250, fun_obj=...) at quickjs.c:36568
#23 0x000000000043e1ee in eval_buf (ctx=0xa2d3250, buf=0xa2ea010, filename=0x7fffffffe547 "/tmp/PoC/qjs/3_m/979ac40f6ca100d03c2ffa726ed4a205.0001ce29.honggfuzz.cov",
eval_flags=, buf_len=) at qjs.c:62
#24 eval_file (ctx=ctx@entry=0xa2d3250, filename=0x7fffffffe547 "/tmp/PoC/qjs/3_m/979ac40f6ca100d03c2ffa726ed4a205.0001ce29.honggfuzz.cov", module=,
module@entry=1, strict=strict@entry=0) at qjs.c:101
#25 0x000000000043d840 in main (argc=3, argv=) at qjs.c:519
(gdb)