-
Bug
-
Resolution: Won't Do
-
Undefined
-
None
-
rhel-7.9.z, rhel-8.8.0, rhel-9.3.0
-
None
-
None
-
None
-
rhel-sst-cs-plumbers
-
ssg_core_services
-
None
-
False
-
-
None
-
Red Hat Enterprise Linux
-
None
-
None
-
None
-
-
All
-
None
After providing a test package with the fix for bash hang due to unsafe call to malloc from signal handler - PIPESTATUS variable issue
the customer experienced a new race condition:
(gdb) bt
#0 __lll_lock_wait_private () at ../nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:95
#1 0x00007f6d3e94ab12 in _L_lock_16654 () at malloc.c:5190
#2 0x00007f6d3e947753 in {}GI{}_libc_malloc (bytes=140107181496160, bytes@entry=8) at malloc.c:2903
#3 0x000000000046a91b in xmalloc (bytes=8) at xmalloc.c:112
#4 0x0000000000454cc3 in run_exit_trap () at trap.c:742
#5 0x0000000000456d94 in termsig_handler (sig=15) at sig.c:562
#6 0x0000000000440f6b in waitchld (block=block@entry=0, wpid=-1) at jobs.c:3090
#7 0x0000000000441508 in sigchld_handler (sig=<optimized out>) at jobs.c:3053
#8 <signal handler called>
#9 _int_malloc (av=av@entry=0x7f6d3ec89760 <main_arena>, bytes=bytes@entry=128) at malloc.c:3464
#10 0x00007f6d3e9476fc in {}GI{}_libc_malloc (bytes=bytes@entry=128) at malloc.c:2905
#11 0x000000000046a9e5 in xrealloc (pointer=pointer@entry=0x0, bytes=bytes@entry=128) at xmalloc.c:133
#12 0x000000000044a0c7 in read_comsub (rflag=<synthetic pointer>, quoted=<optimized out>, fd=<optimized out>) at subst.c:5193
#13 command_substitute (string=string@entry=0x148fd20 "ls", quoted=quoted@entry=0) at subst.c:5443
#14 0x000000000044cc7d in param_expand (string=string@entry=0x148f2e0 "$(ls)", sindex=sindex@entry=0x7ffe26a1296c, quoted=quoted@entry=0, expanded_something=expanded_something@entry=0x7ffe26a12a30,
contains_dollar_at=contains_dollar_at@entry=0x7ffe26a12978, quoted_dollar_at_p=quoted_dollar_at_p@entry=0x7ffe26a12970, had_quoted_null_p=had_quoted_null_p@entry=0x7ffe26a12974, pflags=0) at subst.c:7758
#15 0x000000000044fe47 in expand_word_internal (word=<optimized out>, quoted=quoted@entry=0, isexp=isexp@entry=0, contains_dollar_at=contains_dollar_at@entry=0x7ffe26a12a34,
expanded_something=expanded_something@entry=0x7ffe26a12a30) at subst.c:8152
#16 0x0000000000452032 in shell_expand_word_list (eflags=31, tlist=0x14912d0) at subst.c:9259
#17 expand_word_list_internal (list=<optimized out>, eflags=eflags@entry=31) at subst.c:9376
#18 0x000000000045282a in expand_words (list=<optimized out>) at subst.c:8998
#19 0x0000000000430c70 in execute_simple_command (simple_command=<optimized out>, pipe_in=pipe_in@entry=-1, pipe_out=pipe_out@entry=-1, async=async@entry=0, fds_to_close=fds_to_close@entry=0x148f2c0)
at execute_cmd.c:3833
#20 0x0000000000432393 in execute_command_internal (command=0x1490be0, asynchronous=0, pipe_in=-1, pipe_out=-1, fds_to_close=0x148f2c0) at execute_cmd.c:765
#21 0x0000000000433d7e in execute_command (command=0x1490be0) at execute_cmd.c:386
#22 0x000000000041e3b5 in reader_loop () at eval.c:153
#23 0x000000000041ca1e in main (argc=2, argv=0x7ffe26a12eb8, env=0x7ffe26a12ed0) at shell.c:759
as you can see, the problem is the race condition in frame #4:
(gdb) frame 4
#4 0x0000000000454cc3 in run_exit_trap () at trap.c:742
742 trap_command = savestring (trap_list[EXIT_TRAP]);
The patch for the PIPESTATUS variable runs was not enough.
A possible (untested) pseudo patch could be:
trap.c:run_exit_trap ()
...
- char *trap_command;
+ char trap_command[8192];
...
+ trap_command = savestring (trap_list[EXIT_TRAP]);
{{+ if (trap_list[EXIT_TRAṔ])
{ strncpy (trap_command, trap_list[EXIT_TRAP], 8192); trap_command[8191] = 0; } }}else trap_command = "";
...
8192 is hopefully a sane size for a exit trap. Could increase it, or cause an error if it is larger.
The exit_trap () code does not release the trap_command string, and it is not
released in the first levels of the code:
parse_and_execute (trap_command, "exit trap", SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE);
so, it might even be safe to just patch as:
- trap_command = savestring (trap_list[EXIT_TRAP]);
{{+ trap_command = trap_list[EXIT_TRAṔ] ? trap_list[EXIT_TRAP] : "";}}
but possibly some other race condition will be found after such fix, and the string might be modified in the parse_and_execute call, what probably would not cause harm as it is exiting.