tig
tig copied to clipboard
SIGSEGV or assertion failure on search
There's a failed assertion (or if assertions are disabled, a SIGSEGV) when loading tig as tig blame path/to/file and then immediately executing /search-token<CR>, first observed in 06f7d75 and confirmed still present in master as of e543cfe5a2464613f9f9bc716e01ecdcc702dcff.
The assertion:
tig: malloc.c:4033: _int_malloc: Assertion `(unsigned long) (size) >= (unsigned long) (nb)' failed.
The call stack (without line numbers, but it's pretty clear):
0x00007f31f1ceefb7 in raise () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) bt
#0 0x00007f31f1ceefb7 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007f31f1cf0921 in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00007f31f1d44c03 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#3 0x00007f31f1d471cc in malloc () from /lib/x86_64-linux-gnu/libc.so.6
#4 0x00007f31f1daaf51 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#5 0x00007f31f1db13c2 in regcomp () from /lib/x86_64-linux-gnu/libc.so.6
#6 0x00007f31f2f7b0e3 in setup_and_find_next ()
#7 0x00007f31f2f7af72 in search_view ()
#8 0x00007f31f2f56b66 in view_driver ()
#9 0x00007f31f2f55e5f in main ()
I haven't looked into it at all yet, but logging it here for posterity.
Discovered that this happens when tig is built with -march=native using clang 16 or gcc 11 (so unlikely to be a compiler bug). On this machine (TR 1950X) -march=native translates into the following features:
+m128bit-long-double+m64+m80387+mabm+madx+maes+malign-stringops+mavx+mavx2+mavx256-split-unaligned-store+mbmi+mbmi2+mclflushopt+mclzero+mcx16+mf16c+mfancy-math-387+mfma+mfp-ret-in-387+mfsgsbase+mfxsr+mglibc+mhard-float+mieee-fp+mlong-double-80+mlzcnt+mmmx+mmovbe+mmwaitx+mpclmul+mpopcnt+mprefer-avx128+mprfchw+mpush-args+mrdrnd+mrdseed+mred-zone+msahf+msha+msse+msse2+msse3+msse4+msse4.1+msse4.2+msse4a+mssse3+mstv+mtls-direct-seg-refs+mvzeroupper+mxsave+mxsavec+mxsaveopt+mxsaves
Something in this causes memory corruption as reported by ASAN:
=================================================================
==14959==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x604000001b00 at pc 0x7f7b944e466e bp 0x7fffe4d389d0 sp 0x7fffe4d38190
WRITE of size 64 at 0x604000001b00 thread T0
#0 0x7f7b944e466d in regcomp (/usr/local/bin/tig+0xc566d) (BuildId: ee62ee7c120b3b1c4c01d914418469ca48afba10)
#1 0x7f7b945b330b in setup_and_find_next search.c
#2 0x7f7b945b2e2a in search_view search.c
#3 0x7f7b945496f5 in view_driver tig.c
#4 0x7f7b94547d38 in main tig.c
#5 0x7f7b922b1bf6 in __libc_start_main /build/glibc-S9d2JN/glibc-2.27/csu/../csu/libc-start.c:310
#6 0x7f7b94474869 in _start (/usr/local/bin/tig+0x55869) (BuildId: ee62ee7c120b3b1c4c01d914418469ca48afba10)
0x604000001b00 is located 0 bytes after 48-byte region [0x604000001ad0,0x604000001b00)
allocated by thread T0 here:
#0 0x7f7b9450d668 in calloc (/usr/local/bin/tig+0xee668) (BuildId: ee62ee7c120b3b1c4c01d914418469ca48afba10)
#1 0x7f7b945b311d in setup_and_find_next search.c
#2 0x7f7b945b2e2a in search_view search.c
#3 0x7f7b945496f5 in view_driver tig.c
#4 0x7f7b94547d38 in main tig.c
#5 0x7f7b922b1bf6 in __libc_start_main /build/glibc-S9d2JN/glibc-2.27/csu/../csu/libc-start.c:310
SUMMARY: AddressSanitizer: heap-buffer-overflow (/usr/local/bin/tig+0xc566d) (BuildId: ee62ee7c120b3b1c4c01d914418469ca48afba10) in regcomp
Shadow bytes around the buggy address:
0x604000001880: fa fa 00 00 00 00 07 fa fa fa 00 00 00 00 00 07
0x604000001900: fa fa 00 00 00 00 00 01 fa fa 00 00 00 00 07 fa
0x604000001980: fa fa 00 00 00 00 00 05 fa fa 00 00 00 00 00 02
0x604000001a00: fa fa 00 00 00 00 07 fa fa fa 00 00 00 00 01 fa
0x604000001a80: fa fa 00 00 00 00 05 fa fa fa 00 00 00 00 00 00
=>0x604000001b00:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x604000001b80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x604000001c00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x604000001c80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x604000001d00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x604000001d80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
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
==14959==ABORTING
Just as a test, I tried increasing the size allocated for the preg parameter to regcomp(), and with this change tig no longer crashes (this is obviously not a fix):
diff --git a/src/search.c b/src/search.c
index f786620..843a985 100644
--- a/src/search.c
+++ b/src/search.c
@@ -69,7 +69,7 @@ setup_and_find_next(struct view *view, enum request request)
regex_flags |= REG_ICASE;
if (!view->regex) {
- view->regex = calloc(1, sizeof(*view->regex));
+ view->regex = calloc(1, sizeof(*view->regex) * 2);
if (!view->regex)
return ERROR_OUT_OF_MEMORY;
}
This is under Linux (Ubuntu 18.04) with tig linked against libpcre2-8.so.0. I should probably try manually building against the latest prce2 library to see if this reproduces with later versions.
Maybe libpcre2 would need to be compiled with the same -march=native option.
I remember having similar problems on Ubuntu 16, without custom CFLAGS. I worked around it by disabling PCRE support.. Perhaps it's an incompatiblity with old libpcre2