prism
prism copied to clipboard
Out-of-bounds read in parser_lex_magic_comment
On 1da0733f147ed0a4547791576db53c04780cd498, compile and run testcase.c below to see an out-of-bounds read:
// testcase.c
#include <prism.h>
/*
00000000: 2330 2020 3a22 2020 20 #0 :"
*/
uint8_t input[] = {
0x23, 0x30, 0x20, 0x20, 0x3a, 0x22, 0x20, 0x20, 0x20
};
int main(int argc, const char **argv) {
(void)argc;
(void)argv;
pm_parse_success_p(input, sizeof(input), NULL);
return 0;
}
$ clang -Iinclude $(find src -name "*.c") -ggdb3 testcase.c -fsanitize=address -o testcase
$ ./testcase
=================================================================
==315==ERROR: AddressSanitizer: global-buffer-overflow on address 0xaaaadacba4e9 at pc 0xaaaadab10b3c bp 0xffffedbe2010 sp 0xffffedbe2008
READ of size 1 at 0xaaaadacba4e9 thread T0
#0 0xaaaadab10b38 in parser_lex_magic_comment /prism/src/prism.c:8446:17
#1 0xaaaadaaf8ca0 in parser_lex /prism/src/prism.c:10756:26
#2 0xaaaadaaf3364 in parse_program /prism/src/prism.c:22582:5
#3 0xaaaadaaf3188 in pm_parse /prism/src/prism.c:23015:12
#4 0xaaaadaaf4188 in pm_parse_success_p /prism/src/prism.c:23132:23
#5 0xaaaadabfe434 in main /prism/testcase.c:14:5
#6 0xffff8a2e73fc in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#7 0xffff8a2e74d4 in __libc_start_main csu/../csu/libc-start.c:392:3
#8 0xaaaada9a302c in _start (/prism/testcase+0x5302c) (BuildId: 4c7d9b6907377a5562c1c5abc735c0746255a118)
0xaaaadacba4e9 is located 0 bytes after global variable 'input' defined in '/prism/testcase.c:7' (0xaaaadacba4e0) of size 9
SUMMARY: AddressSanitizer: global-buffer-overflow /prism/src/prism.c:8446:17 in parser_lex_magic_comment
Shadow bytes around the buggy address:
0xaaaadacba200: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0xaaaadacba280: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0xaaaadacba300: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0xaaaadacba380: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
0xaaaadacba400: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
=>0xaaaadacba480: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 00[01]f9 f9
0xaaaadacba500: f9 f9 f9 f9 f9 f9 f9 f9 00 00 00 00 00 00 00 00
0xaaaadacba580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0xaaaadacba600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0xaaaadacba680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0xaaaadacba700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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
==315==ABORTING
diff --git a/src/prism.c b/src/prism.c
index 186cdd35..3d6cd3e2 100644
--- a/src/prism.c
+++ b/src/prism.c
@@ -8443,7 +8443,7 @@ parser_lex_magic_comment(pm_parser_t *parser, bool semantic_token_seen) {
if (*cursor == '\\' && (cursor + 1 < end)) cursor++;
}
value_end = cursor;
- if (*cursor == '"') cursor++;
+ if (cursor < end && *cursor == '"') cursor++;
} else {
value_start = cursor;
while (cursor < end && *cursor != '"' && *cursor != ';' && !pm_char_is_whitespace(*cursor)) cursor++;
seems to fix the issue.