tac -r x x
Version:
coreutils-6.11 (fixed in 6.12)
How to reproduce?
use the command
$ echo >x;
$ tac -r x x
Symptom:
Crash.
Accessing uninitialized pointer “regs.start’.
The backtrace:
#0 0x0000003998030265 in raise () from /lib64/libc.so.6
#1 0x0000003998031d10 in abort () from /lib64/libc.so.6
#2 0x000000399806a84b in __libc_message () from /lib64/libc.so.6
#3 0x0000003998075421 in realloc () from /lib64/libc.so.6
#4 0x0000000000410cdc in re_copy_regs (regs=0x7fff852e3ed0, pmatch=0x14ba61e0, nregs=1, regs_allocated=1) at regexec.c:540
#5 0x0000000000410b29 in re_search_stub (bufp=0x626500, string=0x14ba6991 "\n", length=1, start=0, range=0, stop=1, regs=0x7fff852e3ed0, ret_len=false) at regexec.c:487
#6 0x0000000000410678 in rpl_re_search (bufp=0x626500, string=0x14ba6991 "\n", length=1, start=0, range=0, regs=0x7fff852e3ed0) at regexec.c:332
#7 0x0000000000401c80 in tac_seekable (input_fd=6, file=0x7fff852e4b14 "x") at tac.c:266
#8 0x000000000040257f in tac_file (filename=0x7fff852e4b14 "x") at tac.c:550
#9 0x0000000000402995 in main (argc=4, argv=0x7fff852e4168) at tac.c:656
Root cause:
regs is not initialized in ‘tac_seekable’:
static bool
tac_seekable (int input_fd, const char *file)
{
/* regs is never initialized. */
struct re_registers regs;
The fix is to declare regs as a global variable so it’s initialized as 0.
/* global static */
+ static struct re_registers regs;
tac_seekable (int input_fd, const char *file)
{
.. ..
- struct re_registers regs;
Does the application print Error Message?
No. The “segmentation fault” msg is printed by the OS, instead of the application level software.
Can we anticipate error and put a magic error message?
Yes. Exception signal pattern!