| Summary: | Buffer overflow with _FORTIFY_SOURCE=3 in fixdep | ||
|---|---|---|---|
| Product: | Busybox | Reporter: | Sam James <sam> |
| Component: | Other | Assignee: | unassigned |
| Status: | RESOLVED FIXED | ||
| Severity: | normal | CC: | busybox-cvs |
| Priority: | P5 | ||
| Version: | 1.35.x | ||
| Target Milestone: | --- | ||
| Hardware: | All | ||
| OS: | Linux | ||
| Host: | x86_64-pc-linux-gnu | Target: | |
| Build: | x86_64-pc-linux-gnu | ||
| Attachments: | /tmp/kxgettext.o.d | ||
|
Description
Sam James
2023-02-10 02:19:42 UTC
I can reproduce in a fresh tarball of 1.36.0 after untarring with: 1. make HOSTCCFLAGS="-O2 -ggdb3 -D_FORTIFY_SOURCE=3" scripts_basic 2. cp /tmp/kxgettext.o.d scripts/kconfig/ 3. scripts/basic/fixdep scripts/kconfig/.kxgettext.o.d scripts/kconfig/kxgettext.o $'x86_64-pc-linux-gnu-gcc -Wp,-MD,scripts/kconfig/.kxgettext.o.d -O2 -ggdb3 -c -o scripts/kconfig/kxgettext.o scripts/kconfig/kxgettext.c' Created attachment 9501 [details]
/tmp/kxgettext.o.d
fwiw I can reproduce with: - gcc 13.0.1 20230205 (unreleased) - gcc 12.2.1 20230204 - clang 15.0.7 ... and without FORTIFY_SOURCE, it just corrupts: ``` Program received signal SIGSEGV, Segmentation fault. 0x0000682e6f746f72 in ?? () (gdb) bt #0 0x0000682e6f746f72 in ?? () #1 0x0000000000000000 in ?? () `` huh, I can get it to crash with scripts/kconfig/.kxgettext.o.d as: ``` /tmp/garbage: \ /usr/include/stdlib.h \ ``` ``` # scripts/basic/fixdep scripts/kconfig/.kxgettext.o.d scripts/kconfig/kxgettext.o $'clang-15 -Wp,-MD,scripts/kconfig/.kxgettext.o.d -O2 -ggdb3 -c -o scripts/kconfig/kxqgettext.o scripts/kconfig/kxgettext.c' cmd_scripts/kconfig/kxgettext.o := clang-15 -Wp,-MD,scripts/kconfig/.kxgettext.o.d -O2 -ggdb3 -c -o scripts/kconfig/kxqgettext.o scripts/kconfig/kxgettext.c deps_scripts/kconfig/kxgettext.o := \ /usr/include/stdlib.h \ Segmentation fault (core dumped) ``` (In reply to Sam James from comment #0) p = memchr(m, ':', len); if (!p) { fprintf(stderr, "fixdep: parse error\n"); exit(1); } memcpy(s, m, p-m); s[p-m] = 0; > Note the large length in memcpy: > Breakpoint 1.4, memcpy (__len=18446744073709551614, __src=0x7ffff7fc3a24, __dest=0x7fffffffd5f0) at /usr/include/bits/string_fortified.h:29 29 return __builtin___memcpy_chk (__dest, __src, __len, So, the __len is -2. > #1 parse_dep_file (map=map@entry=0x7ffff7fc3000, len=<optimized out>) at scripts/basic/fixdep.c:341 > m = 0x7ffff7fc3a24 "" > end = 0x7ffff7fc3a24 "" > p = 0x7ffff7fc3a22 "\n\n" > s = 0x7fffffffd5f0 "scripts/kconfig/lkc_proto.h" Well... looks like memchr(m, ':', len) returned a pointer two bytes BEFORE the start of the search string (!!!), so (p-m) evaluated to -2, which code rightly does not expect. Can you investigate further why memchr() does this? E.g. is it getting bogus "len" parameter? Is it just buggy? Fixed in git. |