From: Fengfei.Xi
To: [email protected]
Subject: Bash crash when malloc is called in a signal handler.

Machine: aarch64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -g -O2 -fstack-protector-strong -Wformat 
-Werror=format-security -Wall
uname output: Linux XXXX 6.1.146-rt53 #1 SMP PREEMPT_RT Tue Jan 27 19:45:48 CST 
2026 aarch64 GNU/Linux
Machine Type: aarch64-linux-gnu

Glibc version: 2.36-9+deb12u10

Bash Version: 5.2
Patch Level: 15
Release Status: release

Description:

We have encountered several very low-probability Bash coredump issues in 
production.

The stack trace is shown below:
Program terminated with signal SIGABRT, Aborted.
(gdb) bt
#0  0x0000ffffa9b2a98c in __GI_kill () at ../sysdeps/unix/syscall-template.S:120
#1  0x0000aaaabedb7070 in ?? ()
#2  0x0000aaaabedb7424 in termsig_sighandler ()
#3  <signal handler called>
#4  __pthread_kill_implementation (threadid=281473531132736, 
signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44
#5  0x0000ffffa9b70ab4 in __pthread_kill_internal (signo=6, threadid=<optimized 
out>) at ./nptl/pthread_kill.c:78
#6  0x0000ffffa9b2a72c in __GI_raise (sig=sig@entry=6) at 
../sysdeps/posix/raise.c:26
#7  0x0000ffffa9b1747c in __GI_abort () at ./stdlib/abort.c:79
#8  0x0000ffffa9b64aac in __libc_message (action=action@entry=do_abort, 
fmt=fmt@entry=0xffffa9c46d28 "%s\n") at ../sysdeps/posix/libc_fatal.c:156
#9  0x0000ffffa9b7aebc in malloc_printerr (str=str@entry=0xffffa9c42558 
"malloc(): unsorted double linked list corrupted") at ./malloc/malloc.c:5660
#10 0x0000ffffa9b7df84 in _int_malloc (av=av@entry=0xffffa9c90af0 <main_arena>, 
bytes=bytes@entry=32) at ./malloc/malloc.c:4006
#11 0x0000ffffa9b7f13c in __GI___libc_malloc (bytes=32) at 
./malloc/malloc.c:3315
#12 0x0000aaaabedd12c4 in xmalloc ()
#13 0x0000aaaabedb9f64 in array_copy ()
#14 0x0000aaaabedb2f20 in run_exit_trap ()
#15 0x0000aaaabedb71ec in ?? ()
#16 0x0000aaaabedb732c in termsig_handler ()
#17 0x0000aaaabed94af8 in ?? ()
#18 0x0000aaaabed95140 in ?? ()
#19 <signal handler called>
#20 _int_malloc (av=av@entry=0xffffa9c90af0 <main_arena>, bytes=bytes@entry=32) 
at ./malloc/malloc.c:4050
#21 0x0000ffffa9b7f13c in __GI___libc_malloc (bytes=32) at 
./malloc/malloc.c:3315
#22 0x0000aaaabedd12c4 in xmalloc ()
#23 0x0000aaaabedb5818 in add_unwind_protect ()
#24 0x0000aaaabeda43a8 in command_substitute ()
#25 0x0000aaaabeda6614 in ?? ()
#26 0x0000aaaabeda91a4 in ?? ()
#27 0x0000aaaabeda99b0 in ?? ()
#28 0x0000aaaabedaad5c in ?? ()
#29 0x0000aaaabed7da64 in execute_command_internal ()
#30 0x0000aaaabed7f6d0 in execute_command ()
#31 0x0000aaaabed7cd98 in execute_command_internal ()
#32 0x0000aaaabedd9b40 in parse_and_execute ()
#33 0x0000aaaabedd9cb4 in evalstring ()
#34 0x0000aaaabed78fa0 in ?? ()
#35 0x0000aaaabed7f298 in execute_command_internal ()
#36 0x0000aaaabedd9b40 in parse_and_execute ()
#37 0x0000aaaabedd883c in ?? ()
#38 0x0000aaaabedd8a68 in source_file ()
#39 0x0000aaaabede4d2c in source_builtin ()
#40 0x0000aaaabed78fa0 in ?? ()
#41 0x0000aaaabed7f298 in execute_command_internal ()
#42 0x0000aaaabed81598 in ?? ()
#43 0x0000aaaabed7c500 in execute_command_internal ()
#44 0x0000aaaabed7f6d0 in execute_command ()
#45 0x0000aaaabed7cdd8 in execute_command_internal ()
#46 0x0000aaaabed7cd20 in execute_command_internal ()
#47 0x0000aaaabed80964 in ?? ()
#48 0x0000aaaabed7f598 in execute_command_internal ()
#49 0x0000aaaabedd9b40 in parse_and_execute ()
#50 0x0000aaaabedd883c in ?? ()
#51 0x0000aaaabedd8a68 in source_file ()
#52 0x0000aaaabede4d2c in source_builtin ()
#53 0x0000aaaabed78fa0 in ?? ()
#54 0x0000aaaabed7f298 in execute_command_internal ()
#55 0x0000aaaabedd9b40 in parse_and_execute ()
#56 0x0000aaaabedd883c in ?? ()
#57 0x0000aaaabedd8a68 in source_file ()
#58 0x0000aaaabede4d2c in source_builtin ()
#59 0x0000aaaabed78fa0 in ?? ()
#60 0x0000aaaabed7f298 in execute_command_internal ()
#61 0x0000aaaabed7f6d0 in execute_command ()
#62 0x0000aaaabed7cdd8 in execute_command_internal ()
#63 0x0000aaaabed7f6d0 in execute_command ()
#64 0x0000aaaabed7cdd8 in execute_command_internal ()
#65 0x0000aaaabedd9b40 in parse_and_execute ()
#66 0x0000aaaabedd883c in ?? ()
#67 0x0000aaaabedd8990 in maybe_execute_file ()
#68 0x0000aaaabed643a4 in main ()

After examining the stack traces, it appears that the crashes occur when Bash 
is executing inside malloc and a signal interrupts the execution.

4046           /* remove from unsorted list */
4047           if (__glibc_unlikely (bck->fd != victim))
4048             malloc_printerr ("malloc(): corrupted unsorted chunks 3");
4049           unsorted_chunks (av)->bk = bck;
4050           bck->fd = unsorted_chunks (av);      <<-----

The signal handler then reenters malloc, which eventually detects inconsistent 
internal allocator state and triggers SIGABRT, leading to a coredump.

According to the POSIX documentation and the signal-safety(7) manual page, 
calling malloc inside a signal handler is not async-signal-safe. We also 
noticed that similar scenarios have been discussed previously on the mailing 
list(https://lists.gnu.org/archive/html/bug-bash/2011-11/msg00021.html).

Our current understanding is that the signal handler in Bash may indirectly 
invoke memory allocation, which could lead to allocator reentrancy when a 
signal arrives during a malloc operation.

Could you please advise whether this issue is already known or if there is any 
recommended mitigation or fix for this scenario in recent Bash versions?

Any guidance would be greatly appreciated.

Reply via email to