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!