You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the bug
An insufficient fix for CVE-2023-50268 has led to a stack-buffer-overflow in the master branch of jq.
To Reproduce
Hi team, thanks for your great work! While analyzing CVE-2023-50268, I discovered that the vulnerability has not been fully addressed. Although commit c9a5156 attempted to fix the issue by introducing a decNumberUnit member in res to prevent overflow when handling large numbers, this fix is insufficient. The decNumberUnit can only store a limited range of values, leaving relatively large numbers still capable of crashing the program.
To reproduce the issue, compile the master branch with the following configuration: ./configure CFLAGS="-g -O0 -fno-inline -rdynamic -fsanitize=address" CXXFLAGS="-g -O0 -fno-inline -rdynamic -fsanitize=address" LDFLAGS="-fsanitize=address"
and do
./jq '1 != .' <<<Nan100000000000000000000000000
you will see
==266385==ERROR: AddressSanitizer: stack-buffer-overflowonaddress0x7ffe4ea915e0atpc0x7fa3b0b8b819bp0x7ffe4ea91380sp0x7ffe4ea91378WRITEofsize2at0x7ffe4ea915e0threadT0#0 0x7fa3b0b8b818 in decNumberCopy src/decNumber/decNumber.c:3375
#1 0x7fa3b0ba24e5 in decNaNs src/decNumber/decNumber.c:7706
#2 0x7fa3b0b9a979 in decCompareOp src/decNumber/decNumber.c:6085
#3 0x7fa3b0b7d7da in decNumberCompare src/decNumber/decNumber.c:858
#4 0x7fa3b0b46e11 in jvp_number_cmp src/jv.c:748
#5 0x7fa3b0b47040 in jvp_number_equal src/jv.c:773
#6 0x7fa3b0b5256f in jv_equal src/jv.c:1922
#7 0x7fa3b0b18bc8 in binop_notequal src/builtin.c:409
#8 0x7fa3b0b10721 in f_notequal src/builtin.c:57
#9 0x7fa3b0b3c8cd in jq_next src/execute.c:919
#10 0x5606c9c0604c in process src/main.c:180
#11 0x5606c9c0947a in main src/main.c:666
#12 0x7fa3b0855249 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#13 0x7fa3b0855304 in __libc_start_main_impl ../csu/libc-start.c:360
#14 0x5606c9c05590 in _start
Address0x7ffe4ea915e0islocatedinstackofthreadT0atoffset48inframe#0 0x7fa3b0b46b90 in jvp_number_cmp src/jv.c:737
Thisframehas3object(s):
[32, 48) 'res' (line746) <==Memoryaccessatoffset48overflowsthisvariable
[64, 80) 'a' (line737)
[96, 112) 'b' (line737)
HINT: thismaybea false positiveifyourprogramusessomecustomstackunwindmechanism, swapcontextorvfork
(longjmpandC++exceptions*are*supported)
SUMMARY: AddressSanitizer: stack-buffer-overflowsrc/decNumber/decNumber.c:3375indecNumberCopyShadowbytesaroundthebuggyaddress:
0x100049d4a260: 000000000000000000000000000000000x100049d4a270: 000000000000000000000000000000000x100049d4a280: 0000000000000000000000000000f1f10x100049d4a290: f1f104f3f3f3000000000000000000000x100049d4a2a0: f1f1f1f104f3f3f30000000000000000=>0x100049d4a2b0: 000000000000f1f1f1f10000[f2]f200000x100049d4a2c0: f2f20000f3f3000000000000000000000x100049d4a2d0: 00000000000000000000f1f1f1f100000x100049d4a2e0: f2f20000f3f3000000000000000000000x100049d4a2f0: 000000000000000000000000000000000x100049d4a300: 00000000000000000000000000000000Shadowbytelegend (oneshadowbyterepresents8applicationbytes):
Addressable: 00Partiallyaddressable: 01020304050607Heapleftredzone: faFreedheapregion: fdStackleftredzone: f1Stackmidredzone: f2Stackrightredzone: f3Stackafterreturn: f5Stackuseafterscope: f8Globalredzone: f9Globalinitorder: f6Poisonedbyuser: f7Containeroverflow: fcArraycookie: acIntraobjectredzone: bbASaninternal: feLeftallocaredzone: caRightallocaredzone: cb==266385==ABORTING
Expected behavior
I think it should not crash here, as it can influence many bytes depending on the input number.
What I can see is that jq uses two members (each 2 bytes) to hold relatively large numbers that have more than three digits.
For example, 400 will be stored in one member, and in memory, it looks like 0x90 0x01, as 0x90 = 144 and 0x01 = 1, so: 1 × 256 + 144 = 400
For 4000, one member is not enough, so it is stored as 0x00 0x00 0x04 0x00, which means the lowest three digits are 000, and the first one is 4, adding up to 4000. As we can see, it should be stored in two members (4 bytes), as shown in the source code:
However, when number get tooooo large, like 10000000000000000000, two members would also be insufficient to hold it, leading to a buffer overflow. Maybe we should add a filter or dynamically allocate the variable res. 😊
Thanks! Environment (please complete the following information):
OS and Version: [Debian GNU/Linux 12 ]
jq version [master]
The text was updated successfully, but these errors were encountered:
Describe the bug
An insufficient fix for CVE-2023-50268 has led to a stack-buffer-overflow in the master branch of jq.
To Reproduce
Hi team, thanks for your great work! While analyzing CVE-2023-50268, I discovered that the vulnerability has not been fully addressed. Although commit c9a5156 attempted to fix the issue by introducing a
decNumberUnit
member in res to prevent overflow when handling large numbers, this fix is insufficient. The decNumberUnit can only store a limited range of values, leaving relatively large numbers still capable of crashing the program.To reproduce the issue, compile the master branch with the following configuration:
./configure CFLAGS="-g -O0 -fno-inline -rdynamic -fsanitize=address" CXXFLAGS="-g -O0 -fno-inline -rdynamic -fsanitize=address" LDFLAGS="-fsanitize=address"
and do
you will see
Expected behavior
I think it should not crash here, as it can influence many bytes depending on the input number.
What I can see is that jq uses two members (each 2 bytes) to hold relatively large numbers that have more than three digits.
For example,
400
will be stored in one member, and in memory, it looks like0x90 0x01
, as0x90 = 144
and0x01 = 1
, so:1 × 256 + 144 = 400
For
4000
, one member is not enough, so it is stored as0x00 0x00 0x04 0x00
, which means the lowest three digits are000
, and the first one is4
, adding up to4000
. As we can see, it should be stored in two members (4 bytes), as shown in the source code:However, when number get tooooo large, like 10000000000000000000, two members would also be insufficient to hold it, leading to a buffer overflow. Maybe we should add a filter or dynamically allocate the variable
res
. 😊Thanks!
Environment (please complete the following information):
The text was updated successfully, but these errors were encountered: