Bash-5.2 patch 13
BASH PATCH REPORT = Bash-Release: 5.2 Patch-ID: bash52-013 Bug-Reported-by:Ralf Oehler Bug-Reference-ID: <20221120140252.2fc6489b@bilbo> Bug-Reference-URL: https://lists.gnu.org/archive/html/bug-bash/2022-11/msg00082.html Bug-Description: Bash can leak memory when referencing a non-existent associative array element. Patch (apply with `patch -p0'): *** ../bash-5.2-patched/subst.c 2022-11-05 17:27:48.0 -0400 --- subst.c 2022-11-21 14:42:59.0 -0500 *** *** 7498,7503 : quote_escapes (temp); rflags |= W_ARRAYIND; - if (estatep) - *estatep = es; /* structure copy */ } /* Note that array[*] and array[@] expanded to a quoted null string by --- 7508,7511 *** *** 7508,7512 rflags |= W_HASQUOTEDNULL; ! if (estatep == 0) flush_eltstate (&es); } --- 7516,7522 rflags |= W_HASQUOTEDNULL; ! if (estatep) ! *estatep = es; /* structure copy */ ! else flush_eltstate (&es); } *** ../bash-5.2/patchlevel.h2020-06-22 14:51:03.0 -0400 --- patchlevel.h2020-10-01 11:01:28.0 -0400 *** *** 26,30 looks for to find the patch level (for the sccs version string). */ ! #define PATCHLEVEL 12 #endif /* _PATCHLEVEL_H_ */ --- 26,30 looks for to find the patch level (for the sccs version string). */ ! #define PATCHLEVEL 13 #endif /* _PATCHLEVEL_H_ */ -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/
Bash-5.2 patch 14
BASH PATCH REPORT = Bash-Release: 5.2 Patch-ID: bash52-014 Bug-Reported-by:Andreas Schwab Bug-Reference-ID: Bug-Reference-URL: https://lists.gnu.org/archive/html/bug-bash/2022-10/msg00076.html Bug-Description: Bash defers processing additional terminating signals when running the EXIT trap while exiting due to a terminating signal. This patch allows the new terminating signal to kill the shell immediately. Patch (apply with `patch -p0'): *** ../bash-5.2-patched/execute_cmd.c 2022-11-23 17:09:18.0 -0500 --- execute_cmd.c 2022-11-28 10:36:08.0 -0500 *** *** 3625,3628 --- 3649,3653 dispose_words (es); + QUIT; if (match) *** ../bash-5.2-patched/sig.c 2021-11-04 14:15:31.0 -0400 --- sig.c 2022-12-06 09:45:11.0 -0500 *** *** 95,98 --- 95,99 static void initialize_shell_signals PARAMS((void)); + static void kill_shell PARAMS((int)); void *** *** 487,490 --- 495,500 } + static int handling_termsig = 0; + sighandler termsig_sighandler (sig) *** *** 533,536 --- 543,554 terminate_immediately = 1; + /* If we are currently handling a terminating signal, we have a couple of + choices here. We can ignore this second terminating signal and let the + shell exit from the first one, or we can exit immediately by killing + the shell with this signal. This code implements the latter; to implement + the former, replace the kill_shell(sig) with return. */ + if (handling_termsig) + kill_shell (sig); /* just short-circuit now */ + terminating_signal = sig; *** *** 565,572 int sig; { - static int handling_termsig = 0; - int i, core; - sigset_t mask; - /* Simple semaphore to keep this function from being executed multiple times. Since we no longer are running as a signal handler, we don't --- 585,588 *** *** 574,578 if (handling_termsig) return; ! handling_termsig = 1; terminating_signal = 0; /* keep macro from re-testing true. */ --- 590,595 if (handling_termsig) return; ! ! handling_termsig = terminating_signal; /* for termsig_sighandler */ terminating_signal = 0; /* keep macro from re-testing true. */ *** *** 614,617 --- 631,644 run_exit_trap (); /* XXX - run exit trap possibly in signal context? */ + kill_shell (sig); + } + + static void + kill_shell (sig) + int sig; + { + int i, core; + sigset_t mask; + /* We don't change the set of blocked signals. If a user starts the shell with a terminating signal blocked, we won't get here (and if by some *** ../bash-5.2/patchlevel.h2020-06-22 14:51:03.0 -0400 --- patchlevel.h2020-10-01 11:01:28.0 -0400 *** *** 26,30 looks for to find the patch level (for the sccs version string). */ ! #define PATCHLEVEL 13 #endif /* _PATCHLEVEL_H_ */ --- 26,30 looks for to find the patch level (for the sccs version string). */ ! #define PATCHLEVEL 14 #endif /* _PATCHLEVEL_H_ */ -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/
Re: Nested expansion in heredoc fails
On 12/13/22 12:42 PM, Norbert Lange wrote: Bash Version: 5.2 Patch Level: 2 Release Status: release Description: Parameter expansion within heredocs fails. The code below works with other shells aswell as bash 5.1 Thanks for the report. It's an off-by-one error that is specific to command substitution within parameter expansion in a here-document line. Here's a patch. Chet -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/ *** ../bash-5.2-patched/subst.c 2022-12-13 12:08:58.0 -0500 --- subst.c 2022-12-14 09:09:53.0 -0500 *** *** 1694,1698 CHECK_STRING_OVERRUN (i, si, slen, c); ! tlen = si - i - 1; RESIZE_MALLOCED_BUFFER (result, result_index, tlen + 4, result_size, 64); result[result_index++] = c; --- 1699,1703 CHECK_STRING_OVERRUN (i, si, slen, c); ! tlen = si - i - 2; RESIZE_MALLOCED_BUFFER (result, result_index, tlen + 4, result_size, 64); result[result_index++] = c; *** *** 1714,1718 CHECK_STRING_OVERRUN (i, si, slen, c); ! tlen = si - i - 1; RESIZE_MALLOCED_BUFFER (result, result_index, tlen + 4, result_size, 64); result[result_index++] = c; --- 1719,1723 CHECK_STRING_OVERRUN (i, si, slen, c); ! tlen = si - i - 2; RESIZE_MALLOCED_BUFFER (result, result_index, tlen + 4, result_size, 64); result[result_index++] = c;
Re: Nested expansion in heredoc fails
Hello In bash-5.2, There is one modification: fix to expand $'...' and $"..." in certain word expansions while expanding lines of here-document data This modification has been changed when dealing with '$(', It seems to have missed the right bracket. Maybe we should add this bracket. I hope this patch can fix your problem fix.patch Description: Binary data
Bash-5.2 patch 15
BASH PATCH REPORT = Bash-Release: 5.2 Patch-ID: bash52-015 Bug-Reported-by:Frode Nordahl Bug-Reference-ID: <20221119070714.351759-1-frode.nord...@canonical.com> Bug-Reference-URL: https://lists.gnu.org/archive/html/bug-bash/2022-11/msg00078.html Bug-Description: There are several cases where bash is too aggressive when optimizing out forks in subshells. For example, `eval' and traps should never be optimized. Patch (apply with `patch -p0'): *** ../bash-5.2-patched/builtins/common.h 2022-11-23 17:09:18.0 -0500 --- builtins/common.h 2022-11-19 18:03:59.0 -0500 *** *** 52,55 --- 52,56 #define SEVAL_ONECMD 0x100 /* only allow a single command */ #define SEVAL_NOHISTEXP 0x200 /* inhibit history expansion */ + #define SEVAL_NOOPTIMIZE 0x400/* don't try to set optimization flags */ /* Flags for describe_command, shared between type.def and command.def */ *** ../bash-5.2-patched/builtins/evalstring.c 2022-11-05 17:27:44.0 -0400 --- builtins/evalstring.c 2022-11-19 18:23:21.0 -0500 *** *** 133,138 (command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR || command->value.Connection->connector == ';') && (command->value.Connection->second->flags & CMD_TRY_OPTIMIZING) && ! ((startup_state == 2 && should_suppress_fork (command->value.Connection->second)) || !((subshell_environment & SUBSHELL_PAREN) && should_optimize_fork (command->value.Connection->second, 0 { command->value.Connection->second->flags |= CMD_NO_FORK; --- 133,138 (command->value.Connection->connector == AND_AND || command->value.Connection->connector == OR_OR || command->value.Connection->connector == ';') && (command->value.Connection->second->flags & CMD_TRY_OPTIMIZING) && ! (should_suppress_fork (command->value.Connection->second) || ! ((subshell_environment & SUBSHELL_PAREN) && should_optimize_fork (command->value.Connection->second, 0 { command->value.Connection->second->flags |= CMD_NO_FORK; *** *** 291,294 --- 291,295 (flags & SEVAL_RESETLINE) -> reset line_number to 1 (flags & SEVAL_NOHISTEXP) -> history_expansion_inhibited -> 1 + (flags & SEVAL_NOOPTIMIZE) -> don't try to turn on optimizing flags */ *** *** 503,507 series of connection commands is command->value.Connection->second. */ ! else if (command->type == cm_connection && can_optimize_connection (command)) { command->value.Connection->second->flags |= CMD_TRY_OPTIMIZING; --- 504,510 series of connection commands is command->value.Connection->second. */ ! else if (command->type == cm_connection && ! (flags & SEVAL_NOOPTIMIZE) == 0 && ! can_optimize_connection (command)) { command->value.Connection->second->flags |= CMD_TRY_OPTIMIZING; *** ../bash-5.2-patched/builtins/eval.def 2016-01-25 13:28:37.0 -0500 --- builtins/eval.def 2022-11-19 18:04:25.0 -0500 *** *** 54,57 list = loptend; /* skip over possible `--' */ ! return (list ? evalstring (string_list (list), "eval", SEVAL_NOHIST) : EXECUTION_SUCCESS); } --- 54,57 list = loptend; /* skip over possible `--' */ ! return (list ? evalstring (string_list (list), "eval", SEVAL_NOHIST|SEVAL_NOOPTIMIZE) : EXECUTION_SUCCESS); } *** ../bash-5.2-patched/trap.c 2022-08-10 08:59:45.0 -0400 --- trap.c 2022-12-12 10:57:51.0 -0500 *** *** 305,308 --- 305,309 volatile int save_return_catch_flag, function_code; procenv_t save_return_catch; + char *trap_command, *old_trap; #if defined (ARRAY_VARS) ARRAY *ps; *** *** 420,423 --- 421,427 else { + old_trap = trap_list[sig]; + trap_command = savestring (old_trap); + save_parser_state (&pstate); save_subst_varlist = subst_assign_varlist; *** *** 442,446 if (function_code == 0) ! x = parse_and_execute (savestring (trap_list[sig]), "trap", SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE); else { --- 446,451 if (function_code == 0) ! /* XXX is x always last_command_exit_value? */ ! x = parse_and_execute (trap_command, "trap", SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE|SEVAL_NOOPTIMIZE); else { *** *** 1003,1007 { reset_parser (); !
Re: Nested expansion in heredoc fails
On 12/13/22 12:42 PM, wang yuhang wrote:> This modification has been changed when dealing with '$(', It seems > to have missed the right bracket. Maybe we should add this bracket. It seems that there is something wrong with this patch, It's true that my brain is not very good late at night. Please ignore it
Re: bash crashes if TERM is unset and the Delete key is pressed twice
On 12/13/22 9:00 AM, Emanuele Torre wrote: This happens since 88d69b4fa224d93ef1d26b80229668397bb6496b . If bash is started with the TERM variable unset or empty, it will segfault and crash if you press the Delete key twice (it only happens for the first prompt, and if you don't press anything before the two Delete key presses). I can't reproduce this on macOS, RHEL 7, Fedora 35, or Fedora 37, all using xterm. -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/
Re: bash crashes if TERM is unset and the Delete key is pressed twice
On Wed, Dec 14, 2022 at 12:31:39PM -0500, Chet Ramey wrote: > On 12/13/22 9:00 AM, Emanuele Torre wrote: > > This happens since 88d69b4fa224d93ef1d26b80229668397bb6496b . > > > > If bash is started with the TERM variable unset or empty, it will > > segfault and crash if you press the Delete key twice (it only happens > > for the first prompt, and if you don't press anything before the two > > Delete key presses). > > I can't reproduce this on macOS, RHEL 7, Fedora 35, or Fedora 37, all > using xterm. I can reproduce it consistently on my computer. I tried to figure out what is causing the issue using gdb on the commit 88d69b4fa224d93ef1d26b80229668397bb6496b . It seems that, in readline_internal_charloop(), if the memcpy() at line 593 (introduced with that commit) is present: #if defined (HAVE_POSIX_SIGSETJMP) code = sigsetjmp (_rl_top_level, 0); #else code = setjmp (_rl_top_level); #endif if (code) { (*rl_redisplay_function) (); _rl_want_redisplay = 0; + memcpy ((void *)_rl_top_level, (void *)olevel, sizeof (procenv_t)); /* If we longjmped because of a timeout, handle it here. */ if (RL_ISSTATE (RL_STATE_TIMEOUT)) Then the call to _rl_dispatch() on line 680, causes a segfault: lastc = c; r = _rl_dispatch ((unsigned char)c, _rl_keymap); It is called with those `c' and `_rl_keymap' values (gdb) p c $1 = 27 (gdb) p _rl_keymap $2 = (Keymap) 0x55c653164ae0 Removing that memcpy() call prevents the segfault. Between the memcpy() and _rl_dispatch() call, the program enters only in the following `if' block: if (rl_pending_input == 0) { /* Then initialize the argument and number of keys read. */ _rl_reset_argument (); rl_executing_keyseq[rl_key_sequence_length = 0] = '\0'; } I hope this helps. emanuele6
Re: bash crashes if TERM is unset and the Delete key is pressed twice
On 12/14/22 2:01 PM, Emanuele Torre wrote: On Wed, Dec 14, 2022 at 12:31:39PM -0500, Chet Ramey wrote: On 12/13/22 9:00 AM, Emanuele Torre wrote: This happens since 88d69b4fa224d93ef1d26b80229668397bb6496b . If bash is started with the TERM variable unset or empty, it will segfault and crash if you press the Delete key twice (it only happens for the first prompt, and if you don't press anything before the two Delete key presses). I can't reproduce this on macOS, RHEL 7, Fedora 35, or Fedora 37, all using xterm. I can reproduce it consistently on my computer. I tried to figure out what is causing the issue using gdb on the commit 88d69b4fa224d93ef1d26b80229668397bb6496b . Try this. *** ../bash-20221202/lib/readline/readline.c 2022-12-06 09:48:50.0 -0500 --- lib/readline/readline.c 2022-12-14 14:20:32.0 -0500 *** *** 591,595 (*rl_redisplay_function) (); _rl_want_redisplay = 0; ! memcpy ((void *)_rl_top_level, (void *)olevel, sizeof (procenv_t)); /* If we longjmped because of a timeout, handle it here. */ --- 591,596 (*rl_redisplay_function) (); _rl_want_redisplay = 0; ! if (RL_ISSTATE (RL_STATE_CALLBACK)) ! memcpy ((void *)_rl_top_level, (void *)olevel, sizeof (procenv_t)); /* If we longjmped because of a timeout, handle it here. */ -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/
Re: bash crashes if TERM is unset and the Delete key is pressed twice
On Wed, Dec 14, 2022 at 02:30:04PM -0500, Chet Ramey wrote: > Try this. > > *** ../bash-20221202/lib/readline/readline.c 2022-12-06 09:48:50.0 > -0500 > --- lib/readline/readline.c 2022-12-14 14:20:32.0 -0500 > *** > *** 591,595 > (*rl_redisplay_function) (); > _rl_want_redisplay = 0; > ! memcpy ((void *)_rl_top_level, (void *)olevel, sizeof (procenv_t)); > > /* If we longjmped because of a timeout, handle it here. */ > --- 591,596 > (*rl_redisplay_function) (); > _rl_want_redisplay = 0; > ! if (RL_ISSTATE (RL_STATE_CALLBACK)) > ! memcpy ((void *)_rl_top_level, (void *)olevel, sizeof (procenv_t)); > > /* If we longjmped because of a timeout, handle it here. */ Thank you. That seems to fix the issue. emanuele6
compgen stops processing backslashes after any call to bind
Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wall uname output: Linux debtest 6.0.0-5-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.0.10-2 (2022-12-01) x86_64 GNU/Linux Machine Type: x86_64-pc-linux-gnu Bash Version: 5.2 Patch Level: 2 Release Status: release Description: compgen's behavior regarding backslash processing is altered by any call to bind. Therefore, file and directory names containing a backslash are not completed once bind has been called. Below is an example to reproduce the issue followed by its output. Thanks. Repeat-By: #!/usr/bin/env bash [[ "$(find /tmp/ -maxdepth 1 -type d -name "Dir*")" ]] && exit 2 mkdir /tmp/Dir{\\A,B,\\C} touch /tmp/Dir\\A/file\\A /tmp/DirB/fileB /tmp/Dir\\C/file\\C set -o emacs f_comp() { case "$1" in 1) compgen -f "$2";; 2) compgen -o dirnames -f "$2";; esac } for DF in "/tmp/Dir" "/tmp/Dir\\A" "/tmp/DirB" "/tmp/Dir\\" \ "/tmp/Dir\\A/" "/tmp/DirB/" "/tmp/Dir\\C/" \ "/tmp/Dir\\A/file"; do echo echo "$(( ++COUNT )) compgen1 $DF before bind>>> $(f_comp 1 "$DF")" echo "$COUNT compgen2 $DF before bind>>> $(f_comp 2 "$DF")" done echo; COUNT=0 bind -X for DF in "/tmp/Dir" "/tmp/Dir\\A" "/tmp/DirB" "/tmp/Dir\\" \ "/tmp/Dir\\A/" "/tmp/DirB/" "/tmp/Dir\\C/" \ "/tmp/Dir\\A/file"; do echo echo "$(( ++COUNT )) compgen1 $DF after bind>>> $(f_comp 1 "$DF")" echo "$COUNT compgen2 $DF after bind>>> $(f_comp 2 "$DF")" done rm -rf /tmp/Dir\\* ### Output: 1 compgen1 /tmp/Dir before bind>>> /tmp/Dir\A /tmp/Dir\\\C /tmp/Dir\\B 1 compgen2 /tmp/Dir before bind>>> /tmp/Dir\A /tmp/Dir\\\C /tmp/Dir\\B 2 compgen1 /tmp/Dir\A before bind>>> /tmp/Dir\A 2 compgen2 /tmp/Dir\A before bind>>> /tmp/Dir\A 3 compgen1 /tmp/Dir\\B before bind>>> /tmp/Dir\\B 3 compgen2 /tmp/Dir\\B before bind>>> /tmp/Dir\\B 4 compgen1 /tmp/Dir\\\ before bind>>> /tmp/Dir\\\C 4 compgen2 /tmp/Dir\\\ before bind>>> /tmp/Dir\\\C 5 compgen1 /tmp/Dir\A/ before bind>>> /tmp/Dir\A/file\A 5 compgen2 /tmp/Dir\A/ before bind>>> /tmp/Dir\A/file\A 6 compgen1 /tmp/Dir\\B/ before bind>>> /tmp/Dir\\B/file\\B 6 compgen2 /tmp/Dir\\B/ before bind>>> /tmp/Dir\\B/file\\B 7 compgen1 /tmp/Dir\\\C/ before bind>>> /tmp/Dir\\\C/file\\\C 7 compgen2 /tmp/Dir\\\C/ before bind>>> /tmp/Dir\\\C/file\\\C 8 compgen1 /tmp/Dir\A/file before bind>>> /tmp/Dir\A/file\A 8 compgen2 /tmp/Dir\A/file before bind>>> /tmp/Dir\A/file\A 1 compgen1 /tmp/Dir after bind>>> /tmp/Dir\A /tmp/Dir\\\C /tmp/Dir\\B 1 compgen2 /tmp/Dir after bind>>> /tmp/Dir\A /tmp/Dir\\\C /tmp/Dir\\B 2 compgen1 /tmp/Dir\A after bind>>> 2 compgen2 /tmp/Dir\A after bind>>> /tmp/Dir\A 3 compgen1 /tmp/Dir\\B after bind>>> 3 compgen2 /tmp/Dir\\B after bind>>> /tmp/Dir\\B 4 compgen1 /tmp/Dir\\\ after bind>>> /tmp/Dir\A /tmp/Dir\\\C /tmp/Dir\\B 4 compgen2 /tmp/Dir\\\ after bind>>> /tmp/Dir\A /tmp/Dir\\\C /tmp/Dir\\B 5 compgen1 /tmp/Dir\A/ after bind>>> 5 compgen2 /tmp/Dir\A/ after bind>>> 6 compgen1 /tmp/Dir\\B/ after bind>>> 6 compgen2 /tmp/Dir\\B/ after bind>>> 7 compgen1 /tmp/Dir\\\C/ after bind>>> 7 compgen2 /tmp/Dir\\\C/ after bind>>> 8 compgen1 /tmp/Dir\A/file after bind>>> 8 compgen2 /tmp/Dir\A/file after bind>>>