I reported this downstream first in Gentoo at https://bugs.gentoo.org/893776. Every few attempts (not every time) to build busybox recently, I get: ``` make -j32 -l32 -j1 -s allyesconfig SKIP_SELINUX=y *** buffer overflow detected ***: terminated Aborted (core dumped) make[1]: *** [scripts/Makefile.host:104: scripts/basic/docproc] Error 134 make: *** [Makefile:357: scripts_basic] Error 2 ``` Isolating the command which crashes: ``` # gdb --args 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' [...] cmd_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 deps_scripts/kconfig/kxgettext.o := \ scripts/kconfig/kxgettext.c \ /usr/include/gentoo/fortify.h \ /usr/include/stdlib.h \ /usr/include/bits/libc-header-start.h \ /usr/include/features.h \ /usr/include/features-time64.h \ /usr/include/bits/wordsize.h \ /usr/include/bits/timesize.h \ /usr/include/stdc-predef.h \ /usr/include/sys/cdefs.h \ /usr/include/bits/long-double.h \ /usr/include/gnu/stubs.h \ /usr/include/gnu/stubs-64.h \ /usr/lib/llvm/16/bin/../../../../lib/clang/16/include/stddef.h \ /usr/include/bits/waitflags.h \ /usr/include/bits/waitstatus.h \ /usr/include/bits/floatn.h \ /usr/include/bits/floatn-common.h \ /usr/include/sys/types.h \ /usr/include/bits/types.h \ /usr/include/bits/typesizes.h \ /usr/include/bits/time64.h \ /usr/include/bits/types/clock_t.h \ /usr/include/bits/types/clockid_t.h \ /usr/include/bits/types/time_t.h \ /usr/include/bits/types/timer_t.h \ /usr/include/bits/stdint-intn.h \ /usr/include/endian.h \ /usr/include/bits/endian.h \ /usr/include/bits/endianness.h \ /usr/include/bits/byteswap.h \ /usr/include/bits/uintn-identity.h \ /usr/include/sys/select.h \ /usr/include/bits/select.h \ /usr/include/bits/types/sigset_t.h \ /usr/include/bits/types/__sigset_t.h \ /usr/include/bits/types/struct_timeval.h \ /usr/include/bits/types/struct_timespec.h \ /usr/include/bits/select2.h \ /usr/include/bits/pthreadtypes.h \ /usr/include/bits/thread-shared-types.h \ /usr/include/bits/pthreadtypes-arch.h \ /usr/include/bits/atomic_wide_counter.h \ /usr/include/bits/struct_mutex.h \ /usr/include/bits/struct_rwlock.h \ /usr/include/alloca.h \ /usr/include/bits/stdlib-bsearch.h \ /usr/include/bits/stdlib-float.h \ /usr/include/bits/stdlib.h \ /usr/include/string.h \ /usr/include/bits/types/locale_t.h \ /usr/include/bits/types/__locale_t.h \ /usr/include/strings.h \ /usr/include/bits/strings_fortified.h \ /usr/include/bits/string_fortified.h \ scripts/kconfig/lkc.h \ scripts/kconfig/expr.h \ /usr/include/stdio.h \ /usr/lib/llvm/16/bin/../../../../lib/clang/16/include/stdarg.h \ /usr/include/bits/types/__fpos_t.h \ /usr/include/bits/types/__mbstate_t.h \ /usr/include/bits/types/__fpos64_t.h \ /usr/include/bits/types/__FILE.h \ /usr/include/bits/types/FILE.h \ /usr/include/bits/types/struct_FILE.h \ /usr/include/bits/stdio_lim.h \ /usr/include/bits/stdio2-decl.h \ /usr/include/bits/stdio.h \ /usr/include/bits/stdio2.h \ /usr/lib/llvm/16/bin/../../../../lib/clang/16/include/stdbool.h \ /usr/include/libintl.h \ /usr/include/locale.h \ /usr/include/bits/locale.h \ scripts/kconfig/lkc_proto.h \ *** buffer overflow detected ***: terminated Program received signal SIGABRT, Aborted. 0x00007ffff7e40f0c in ?? () from /usr/lib64/libc.so.6 (gdb) bt #0 0x00007ffff7e40f0c in ?? () from /usr/lib64/libc.so.6 #1 0x00007ffff7defae6 in raise () from /usr/lib64/libc.so.6 #2 0x00007ffff7dd8877 in abort () from /usr/lib64/libc.so.6 #3 0x00007ffff7dd97b8 in ?? () from /usr/lib64/libc.so.6 #4 0x00007ffff7ed415b in __fortify_fail () from /usr/lib64/libc.so.6 #5 0x00007ffff7ed28c6 in __chk_fail () from /usr/lib64/libc.so.6 #6 0x0000555555555b92 in memcpy (__len=18446744073709551614, __src=<optimized out>, __dest=0x7fffffffd5f0) at /usr/include/bits/string_fortified.h:29 #7 parse_dep_file (map=map@entry=0x7ffff7fc3000, len=<optimized out>) at scripts/basic/fixdep.c:341 #8 0x0000555555555dd9 in print_deps () at scripts/basic/fixdep.c:379 #9 0x00005555555552d8 in main (argc=<optimized out>, argv=<optimized out>) at scripts/basic/fixdep.c:411 (gdb) ``` Note the large length in memcpy: ``` (gdb) b /usr/include/bits/string_fortified.h:29 if __len >= 100 warning: failed to validate condition at location 1, disabling: No symbol "__len" in current context. Breakpoint 1 at 0x555555555587: /usr/include/bits/string_fortified.h:29. (4 locations) (gdb) r 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, (gdb) bt full #0 memcpy (__len=18446744073709551614, __src=0x7ffff7fc3a24, __dest=0x7fffffffd5f0) at /usr/include/bits/string_fortified.h:29 No locals. #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" #2 0x0000555555555dd9 in print_deps () at scripts/basic/fixdep.c:379 st = {st_dev = 64512, st_ino = 1074419, st_nlink = 1, st_mode = 33188, st_uid = 250, st_gid = 250, __pad0 = 0, st_rdev = 0, st_size = 2596, st_blksize = 4096, st_blocks = 8, st_atim = { tv_sec = 1675994249, tv_nsec = 352732056}, st_mtim = {tv_sec = 1675994249, tv_nsec = 352732056}, st_ctim = {tv_sec = 1675994249, tv_nsec = 352732056}, __glibc_reserved = {0, 0, 0}} fd = 3 map = 0x7ffff7fc3000 #3 0x00005555555552d8 in main (argc=<optimized out>, argv=<optimized out>) at scripts/basic/fixdep.c:411 No locals. (gdb) ``` I've uploaded a copy of the unpacked source tarball with the needed dep files at https://dev.gentoo.org/~sam/bugs/busybox/busybox-1.35.0-bug893776-fortify-source.tar.xz.
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.