bash: Update version to 5.2 with patches 1 to 15

Message ID 20230328201736.887069-3-adolf.belka@ipfire.org
State Accepted
Commit 7ea6cba07a2cbf21d8a3272ce6371c36df8263ec
Headers
Series bash: Update version to 5.2 with patches 1 to 15 |

Commit Message

Adolf Belka March 28, 2023, 8:17 p.m. UTC
  - Update from version 5.2 patches 1-9 to 5.2 patches 1-15
- Update of rootfile not required
- Changelog
bash52-015
	There are several cases where bash is too aggressive when optimizing out forks
	in subshells. For example, `eval' and traps should never be optimized.
bash52-014
	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.
bash52-013
	Bash can leak memory when referencing a non-existent associative array
	element.
bash52-012
	When running in bash compatibility mode, nested command substitutions can
	leave the `extglob' option enabled.
bash52-011
	Using timeouts and readline editing with the `read' builtin (read -e -t) can
	leave the readline timeout enabled, potentially resulting in an erroneous
	timeout on the next call.
bash52-010
	Bash-5.2 checks the first 128 characters of an executable file that execve()
	refuses to execute to see whether it's a binary file before trying to
	execute it as a shell script. This defeats some previously-supported use
	cases like "self-executing" jar files or "self-uncompressing" scripts.

Signed-off-by: Adolf Belka <adolf.belka@ipfire.org>
---
 lfs/bash                    |   4 +-
 src/patches/bash/bash52-010 |  71 ++++++++
 src/patches/bash/bash52-011 |  45 +++++
 src/patches/bash/bash52-012 | 344 ++++++++++++++++++++++++++++++++++++
 src/patches/bash/bash52-013 |  58 ++++++
 src/patches/bash/bash52-014 | 119 +++++++++++++
 src/patches/bash/bash52-015 | 216 ++++++++++++++++++++++
 7 files changed, 855 insertions(+), 2 deletions(-)
 create mode 100644 src/patches/bash/bash52-010
 create mode 100644 src/patches/bash/bash52-011
 create mode 100644 src/patches/bash/bash52-012
 create mode 100644 src/patches/bash/bash52-013
 create mode 100644 src/patches/bash/bash52-014
 create mode 100644 src/patches/bash/bash52-015
  

Patch

diff --git a/lfs/bash b/lfs/bash
index 14b20b986..c7ef1f946 100644
--- a/lfs/bash
+++ b/lfs/bash
@@ -1,7 +1,7 @@ 
 ###############################################################################
 #                                                                             #
 # IPFire.org - A linux based firewall                                         #
-# Copyright (C) 2007-2022  IPFire Team  <info@ipfire.org>                     #
+# Copyright (C) 2007-2023  IPFire Team  <info@ipfire.org>                     #
 #                                                                             #
 # This program is free software: you can redistribute it and/or modify        #
 # it under the terms of the GNU General Public License as published by        #
@@ -91,7 +91,7 @@  $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
 	cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/bash/bash-4.0-profile-1.patch
 	cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/bash/bash-3.2-ssh_source_bash.patch
 	
-	for i in $$(seq 1 9); do \
+	for i in $$(seq 1 15); do \
 	cd $(DIR_APP) && patch -Np0 < $(DIR_SRC)/src/patches/bash/bash52-$$(printf "%03d" "$${i}") || exit 1; \
 	done
 
diff --git a/src/patches/bash/bash52-010 b/src/patches/bash/bash52-010
new file mode 100644
index 000000000..b58f4a86b
--- /dev/null
+++ b/src/patches/bash/bash52-010
@@ -0,0 +1,71 @@ 
+			     BASH PATCH REPORT
+			     =================
+
+Bash-Release:	5.2
+Patch-ID:	bash52-010
+
+Bug-Reported-by:	larsh@apache.org
+Bug-Reference-ID:
+Bug-Reference-URL:	https://savannah.gnu.org/support/?110744
+
+Bug-Description:
+
+Bash-5.2 checks the first 128 characters of an executable file that execve()
+refuses to execute to see whether it's a binary file before trying to
+execute it as a shell script. This defeats some previously-supported use
+cases like "self-executing" jar files or "self-uncompressing" scripts.
+
+Patch (apply with `patch -p0'):
+
+*** ../bash-5.2-patched/general.c	2022-11-07 10:31:42.000000000 -0500
+--- general.c	2022-11-18 14:48:45.000000000 -0500
+***************
+*** 684,687 ****
+--- 684,688 ----
+  {
+    register int i;
++   int nline;
+    unsigned char c;
+  
+***************
+*** 690,702 ****
+  
+    /* Generally we check the first line for NULs. If the first line looks like
+!      a `#!' interpreter specifier, we just look for NULs anywhere in the
+!      buffer. */
+!   if (sample[0] == '#' && sample[1] == '!')
+!     return (memchr (sample, '\0', sample_len) != NULL);
+  
+    for (i = 0; i < sample_len; i++)
+      {
+        c = sample[i];
+!       if (c == '\n')
+  	return (0);
+        if (c == '\0')
+--- 691,701 ----
+  
+    /* Generally we check the first line for NULs. If the first line looks like
+!      a `#!' interpreter specifier, we look for NULs in the first two lines. */
+!   nline = (sample[0] == '#' && sample[1] == '!') ? 2 : 1;
+  
+    for (i = 0; i < sample_len; i++)
+      {
+        c = sample[i];
+!       if (c == '\n' && --nline == 0)
+  	return (0);
+        if (c == '\0')
+*** ../bash-5.2/patchlevel.h	2020-06-22 14:51:03.000000000 -0400
+--- patchlevel.h	2020-10-01 11:01:28.000000000 -0400
+***************
+*** 26,30 ****
+     looks for to find the patch level (for the sccs version string). */
+  
+! #define PATCHLEVEL 9
+  
+  #endif /* _PATCHLEVEL_H_ */
+--- 26,30 ----
+     looks for to find the patch level (for the sccs version string). */
+  
+! #define PATCHLEVEL 10
+  
+  #endif /* _PATCHLEVEL_H_ */
diff --git a/src/patches/bash/bash52-011 b/src/patches/bash/bash52-011
new file mode 100644
index 000000000..e65a50a2d
--- /dev/null
+++ b/src/patches/bash/bash52-011
@@ -0,0 +1,45 @@ 
+			     BASH PATCH REPORT
+			     =================
+
+Bash-Release:	5.2
+Patch-ID:	bash52-011
+
+Bug-Reported-by:	Fabien Orjollet <of1@disroot.org>
+Bug-Reference-ID:	
+Bug-Reference-URL:	https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1023776
+
+Bug-Description:
+
+Patch (apply with `patch -p0'):
+
+Using timeouts and readline editing with the `read' builtin (read -e -t) can
+leave the readline timeout enabled, potentially resulting in an erroneous
+timeout on the next call.
+
+*** ../bash-5.2-patched/builtins/read.def	2022-06-02 14:23:19.000000000 -0400
+--- builtins/read.def	2022-11-10 10:27:45.000000000 -0500
+***************
+*** 168,171 ****
+--- 168,174 ----
+    if (read_timeout)
+      shtimer_clear (read_timeout);
++ #if defined (READLINE)
++   rl_clear_timeout ();
++ #endif
+    read_timeout = 0;
+  }
+*** ../bash-5.2/patchlevel.h	2020-06-22 14:51:03.000000000 -0400
+--- patchlevel.h	2020-10-01 11:01:28.000000000 -0400
+***************
+*** 26,30 ****
+     looks for to find the patch level (for the sccs version string). */
+  
+! #define PATCHLEVEL 10
+  
+  #endif /* _PATCHLEVEL_H_ */
+--- 26,30 ----
+     looks for to find the patch level (for the sccs version string). */
+  
+! #define PATCHLEVEL 11
+  
+  #endif /* _PATCHLEVEL_H_ */
diff --git a/src/patches/bash/bash52-012 b/src/patches/bash/bash52-012
new file mode 100644
index 000000000..2791542c9
--- /dev/null
+++ b/src/patches/bash/bash52-012
@@ -0,0 +1,344 @@ 
+			     BASH PATCH REPORT
+			     =================
+
+Bash-Release:	5.2
+Patch-ID:	bash52-012
+
+Bug-Reported-by:	Kerin Millar <kfm@plushkava.net>
+Bug-Reference-ID:	<20221002095107.89561bc811e549b55644df11@plushkava.net>
+Bug-Reference-URL:	https://lists.gnu.org/archive/html/bug-bash/2022-10/msg00001.html
+
+Bug-Description:
+
+When running in bash compatibility mode, nested command substitutions can
+leave the `extglob' option enabled.
+
+Patch (apply with `patch -p0'):
+
+*** /fs1/chet/scratch/bash-5.2.12/builtins/shopt.def	2022-11-07 10:31:42.000000000 -0500
+--- builtins/shopt.def	2022-10-14 09:30:11.000000000 -0400
+***************
+*** 150,153 ****
+--- 150,158 ----
+  #endif
+  
++ #if defined (EXTENDED_GLOB)
++ int extglob_flag = EXTGLOB_DEFAULT;
++ static int shopt_set_extglob PARAMS((char *, int));
++ #endif
++ 
+  int expaliases_flag = 0;
+  static int shopt_set_expaliases PARAMS((char *, int));
+***************
+*** 207,211 ****
+  #endif
+  #if defined (EXTENDED_GLOB)
+!   { "extglob", &extended_glob, (shopt_set_func_t *)NULL },
+  #endif
+    { "extquote", &extended_quote, (shopt_set_func_t *)NULL },
+--- 212,216 ----
+  #endif
+  #if defined (EXTENDED_GLOB)
+!   { "extglob", &extglob_flag, shopt_set_extglob },
+  #endif
+    { "extquote", &extended_quote, (shopt_set_func_t *)NULL },
+***************
+*** 378,382 ****
+  
+  #if defined (EXTENDED_GLOB)
+!   extended_glob = EXTGLOB_DEFAULT;
+  #endif
+  
+--- 383,387 ----
+  
+  #if defined (EXTENDED_GLOB)
+!   extended_glob = extglob_flag = EXTGLOB_DEFAULT;
+  #endif
+  
+***************
+*** 644,647 ****
+--- 649,663 ----
+  }
+  
++ #if defined (EXTENDED_GLOB)
++ static int
++ shopt_set_extglob (option_name, mode)
++      char *option_name;
++      int mode;
++ {
++   extended_glob = extglob_flag;
++   return 0;
++ }
++ #endif
++ 
+  #if defined (READLINE)
+  static int
+*** /fs1/chet/scratch/bash-5.2.12/builtins/common.h	2022-11-07 10:31:42.000000000 -0500
+--- builtins/common.h	2022-10-14 09:29:25.000000000 -0400
+***************
+*** 258,261 ****
+--- 258,265 ----
+  #endif
+  
++ #if defined (EXTENDED_GLOB)
++ extern int extglob_flag;
++ #endif
++ 
+  extern int expaliases_flag;
+  
+*** /fs1/chet/scratch/bash-5.2.12/execute_cmd.c	2022-11-07 10:31:42.000000000 -0500
+--- execute_cmd.c	2022-11-02 16:32:12.000000000 -0400
+***************
+*** 3991,4001 ****
+  #endif /* COND_REGEXP */
+  	{
+- 	  int oe;
+- 	  oe = extended_glob;
+  	  extended_glob = 1;
+  	  result = binary_test (cond->op->word, arg1, arg2, TEST_PATMATCH|TEST_ARITHEXP|TEST_LOCALE)
+  				  ? EXECUTION_SUCCESS
+  				  : EXECUTION_FAILURE;
+! 	  extended_glob = oe;
+  	}
+        if (arg1 != nullstr)
+--- 4015,4023 ----
+  #endif /* COND_REGEXP */
+  	{
+  	  extended_glob = 1;
+  	  result = binary_test (cond->op->word, arg1, arg2, TEST_PATMATCH|TEST_ARITHEXP|TEST_LOCALE)
+  				  ? EXECUTION_SUCCESS
+  				  : EXECUTION_FAILURE;
+! 	  extended_glob = extglob_flag;
+  	}
+        if (arg1 != nullstr)
+*** /fs1/chet/scratch/bash-5.2.9/parse.y	2022-11-07 10:31:47.000000000 -0500
+--- parse.y	2022-11-14 11:27:22.000000000 -0500
+***************
+*** 126,130 ****
+  
+  #if defined (EXTENDED_GLOB)
+! extern int extended_glob;
+  #endif
+  
+--- 126,130 ----
+  
+  #if defined (EXTENDED_GLOB)
+! extern int extended_glob, extglob_flag;
+  #endif
+  
+***************
+*** 3305,3309 ****
+    /* Reset to global value of extended glob */
+    if (parser_state & (PST_EXTPAT|PST_CMDSUBST))
+!     extended_glob = global_extglob;
+  #endif
+    if (parser_state & (PST_CMDSUBST|PST_STRING))
+--- 3321,3325 ----
+    /* Reset to global value of extended glob */
+    if (parser_state & (PST_EXTPAT|PST_CMDSUBST))
+!     extended_glob = extglob_flag;
+  #endif
+    if (parser_state & (PST_CMDSUBST|PST_STRING))
+***************
+*** 4125,4132 ****
+  #if defined (EXTENDED_GLOB)
+    /* If (parser_state & PST_EXTPAT), we're parsing an extended pattern for a
+!      conditional command and have already set global_extglob appropriately. */
+    if (shell_compatibility_level <= 51 && was_extpat == 0)
+      {
+!       local_extglob = global_extglob = extended_glob;
+        extended_glob = 1;
+      }
+--- 4143,4150 ----
+  #if defined (EXTENDED_GLOB)
+    /* If (parser_state & PST_EXTPAT), we're parsing an extended pattern for a
+!      conditional command and have already set extended_glob appropriately. */
+    if (shell_compatibility_level <= 51 && was_extpat == 0)
+      {
+!       local_extglob = extended_glob;
+        extended_glob = 1;
+      }
+***************
+*** 4236,4240 ****
+    sh_parser_state_t ps;
+    sh_input_line_state_t ls;
+!   int orig_ind, nc, sflags, start_lineno;
+    char *ret, *ep, *ostring;
+  
+--- 4256,4260 ----
+    sh_parser_state_t ps;
+    sh_input_line_state_t ls;
+!   int orig_ind, nc, sflags, start_lineno, local_extglob;
+    char *ret, *ep, *ostring;
+  
+***************
+*** 4279,4283 ****
+    expand_aliases = 0;
+  #if defined (EXTENDED_GLOB)
+!   global_extglob = extended_glob;		/* for reset_parser() */
+  #endif
+  
+--- 4299,4303 ----
+    expand_aliases = 0;
+  #if defined (EXTENDED_GLOB)
+!   local_extglob = extended_glob;
+  #endif
+  
+***************
+*** 4297,4300 ****
+--- 4317,4323 ----
+    restore_parser_state (&ps);
+  
++ #if defined (EXTENDED_GLOB)
++   extended_glob = local_extglob;
++ #endif
+    token_to_read = 0;
+  
+***************
+*** 4732,4741 ****
+--- 4755,4768 ----
+  
+        /* rhs */
++ #if defined (EXTENDED_GLOB)
+        local_extglob = extended_glob;
+        if (parser_state & PST_EXTPAT)
+  	extended_glob = 1;
++ #endif
+        tok = read_token (READ);
++ #if defined (EXTENDED_GLOB)
+        if (parser_state & PST_EXTPAT)
+  	extended_glob = local_extglob;
++ #endif
+        parser_state &= ~(PST_REGEXP|PST_EXTPAT);
+  
+***************
+*** 4784,4788 ****
+    COND_COM *cexp;
+  
+-   global_extglob = extended_glob;
+    cexp = cond_expr ();
+    return (make_cond_command (cexp));
+--- 4811,4814 ----
+*** y.tab.c.save	2022-11-07 10:31:47.000000000 -0500
+--- y.tab.c	2022-11-18 15:58:03.000000000 -0500
+***************
+*** 176,180 ****
+  
+  #if defined (EXTENDED_GLOB)
+! extern int extended_glob;
+  #endif
+  
+--- 176,180 ----
+  
+  #if defined (EXTENDED_GLOB)
+! extern int extended_glob, extglob_flag;
+  #endif
+  
+***************
+*** 5616,5620 ****
+    /* Reset to global value of extended glob */
+    if (parser_state & (PST_EXTPAT|PST_CMDSUBST))
+!     extended_glob = global_extglob;
+  #endif
+    if (parser_state & (PST_CMDSUBST|PST_STRING))
+--- 5616,5620 ----
+    /* Reset to global value of extended glob */
+    if (parser_state & (PST_EXTPAT|PST_CMDSUBST))
+!     extended_glob = extglob_flag;
+  #endif
+    if (parser_state & (PST_CMDSUBST|PST_STRING))
+***************
+*** 6436,6443 ****
+  #if defined (EXTENDED_GLOB)
+    /* If (parser_state & PST_EXTPAT), we're parsing an extended pattern for a
+!      conditional command and have already set global_extglob appropriately. */
+    if (shell_compatibility_level <= 51 && was_extpat == 0)
+      {
+!       local_extglob = global_extglob = extended_glob;
+        extended_glob = 1;
+      }
+--- 6436,6443 ----
+  #if defined (EXTENDED_GLOB)
+    /* If (parser_state & PST_EXTPAT), we're parsing an extended pattern for a
+!      conditional command and have already set extended_glob appropriately. */
+    if (shell_compatibility_level <= 51 && was_extpat == 0)
+      {
+!       local_extglob = extended_glob;
+        extended_glob = 1;
+      }
+***************
+*** 6547,6551 ****
+    sh_parser_state_t ps;
+    sh_input_line_state_t ls;
+!   int orig_ind, nc, sflags, start_lineno;
+    char *ret, *ep, *ostring;
+  
+--- 6547,6551 ----
+    sh_parser_state_t ps;
+    sh_input_line_state_t ls;
+!   int orig_ind, nc, sflags, start_lineno, local_extglob;
+    char *ret, *ep, *ostring;
+  
+***************
+*** 6590,6594 ****
+    expand_aliases = 0;
+  #if defined (EXTENDED_GLOB)
+!   global_extglob = extended_glob;		/* for reset_parser() */
+  #endif
+  
+--- 6590,6594 ----
+    expand_aliases = 0;
+  #if defined (EXTENDED_GLOB)
+!   local_extglob = extended_glob;
+  #endif
+  
+***************
+*** 6608,6611 ****
+--- 6608,6614 ----
+    restore_parser_state (&ps);
+  
++ #if defined (EXTENDED_GLOB)
++   extended_glob = local_extglob;
++ #endif
+    token_to_read = 0;
+  
+***************
+*** 7043,7052 ****
+--- 7046,7059 ----
+  
+        /* rhs */
++ #if defined (EXTENDED_GLOB)
+        local_extglob = extended_glob;
+        if (parser_state & PST_EXTPAT)
+  	extended_glob = 1;
++ #endif
+        tok = read_token (READ);
++ #if defined (EXTENDED_GLOB)
+        if (parser_state & PST_EXTPAT)
+  	extended_glob = local_extglob;
++ #endif
+        parser_state &= ~(PST_REGEXP|PST_EXTPAT);
+  
+***************
+*** 7095,7099 ****
+    COND_COM *cexp;
+  
+-   global_extglob = extended_glob;
+    cexp = cond_expr ();
+    return (make_cond_command (cexp));
+--- 7102,7105 ----
+*** ../bash-5.2/patchlevel.h	2020-06-22 14:51:03.000000000 -0400
+--- patchlevel.h	2020-10-01 11:01:28.000000000 -0400
+***************
+*** 26,30 ****
+     looks for to find the patch level (for the sccs version string). */
+  
+! #define PATCHLEVEL 11
+  
+  #endif /* _PATCHLEVEL_H_ */
+--- 26,30 ----
+     looks for to find the patch level (for the sccs version string). */
+  
+! #define PATCHLEVEL 12
+  
+  #endif /* _PATCHLEVEL_H_ */
diff --git a/src/patches/bash/bash52-013 b/src/patches/bash/bash52-013
new file mode 100644
index 000000000..3051269c1
--- /dev/null
+++ b/src/patches/bash/bash52-013
@@ -0,0 +1,58 @@ 
+			     BASH PATCH REPORT
+			     =================
+
+Bash-Release:	5.2
+Patch-ID:	bash52-013
+
+Bug-Reported-by:	Ralf Oehler <Ralf@Oehler-Privat.de>
+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.000000000 -0400
+--- subst.c	2022-11-21 14:42:59.000000000 -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.h	2020-06-22 14:51:03.000000000 -0400
+--- patchlevel.h	2020-10-01 11:01:28.000000000 -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_ */
diff --git a/src/patches/bash/bash52-014 b/src/patches/bash/bash52-014
new file mode 100644
index 000000000..c6f3176bf
--- /dev/null
+++ b/src/patches/bash/bash52-014
@@ -0,0 +1,119 @@ 
+			     BASH PATCH REPORT
+			     =================
+
+Bash-Release:	5.2
+Patch-ID:	bash52-014
+
+Bug-Reported-by:	Andreas Schwab <schwab@suse.de>
+Bug-Reference-ID:	<mvmv8opcbha.fsf@suse.de>
+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.000000000 -0500
+--- execute_cmd.c	2022-11-28 10:36:08.000000000 -0500
+***************
+*** 3625,3628 ****
+--- 3649,3653 ----
+  
+  	  dispose_words (es);
++ 	  QUIT;
+  
+  	  if (match)
+*** ../bash-5.2-patched/sig.c	2021-11-04 14:15:31.000000000 -0400
+--- sig.c	2022-12-06 09:45:11.000000000 -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.h	2020-06-22 14:51:03.000000000 -0400
+--- patchlevel.h	2020-10-01 11:01:28.000000000 -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_ */
diff --git a/src/patches/bash/bash52-015 b/src/patches/bash/bash52-015
new file mode 100644
index 000000000..740a13da5
--- /dev/null
+++ b/src/patches/bash/bash52-015
@@ -0,0 +1,216 @@ 
+			     BASH PATCH REPORT
+			     =================
+
+Bash-Release:	5.2
+Patch-ID:	bash52-015
+
+Bug-Reported-by:	Frode Nordahl <frode.nordahl@canonical.com>
+Bug-Reference-ID:	<20221119070714.351759-1-frode.nordahl@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.000000000 -0500
+--- builtins/common.h	2022-11-19 18:03:59.000000000 -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.000000000 -0400
+--- builtins/evalstring.c	2022-11-19 18:23:21.000000000 -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.000000000 -0500
+--- builtins/eval.def	2022-11-19 18:04:25.000000000 -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.000000000 -0400
+--- trap.c	2022-12-12 10:57:51.000000000 -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 ();
+! 	  parse_and_execute (trap_command, "exit trap", SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE);
+  	}
+        else if (code == ERREXIT)
+--- 1008,1012 ----
+  	{
+  	  reset_parser ();
+! 	  parse_and_execute (trap_command, "exit trap", SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE|SEVAL_NOOPTIMIZE);
+  	}
+        else if (code == ERREXIT)
+***************
+*** 1110,1114 ****
+  	}
+  
+!       flags = SEVAL_NONINT|SEVAL_NOHIST;
+        if (sig != DEBUG_TRAP && sig != RETURN_TRAP && sig != ERROR_TRAP)
+  	flags |= SEVAL_RESETLINE;
+--- 1115,1119 ----
+  	}
+  
+!       flags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOOPTIMIZE;
+        if (sig != DEBUG_TRAP && sig != RETURN_TRAP && sig != ERROR_TRAP)
+  	flags |= SEVAL_RESETLINE;
+*** ../bash-5.2-patched/parse.y	2022-11-23 17:09:18.000000000 -0500
+--- parse.y	2022-11-19 18:15:34.000000000 -0500
+***************
+*** 2828,2832 ****
+      last_lastarg = savestring (last_lastarg);
+  
+!   parse_and_execute (savestring (command), vname, SEVAL_NONINT|SEVAL_NOHIST);
+  
+    restore_parser_state (&ps);
+--- 2844,2848 ----
+      last_lastarg = savestring (last_lastarg);
+  
+!   parse_and_execute (savestring (command), vname, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOOPTIMIZE);
+  
+    restore_parser_state (&ps);
+*** ../bash-5.2-patched/jobs.c	2022-07-18 10:19:56.000000000 -0400
+--- jobs.c	2022-11-19 18:10:24.000000000 -0500
+***************
+*** 4221,4225 ****
+    for (i = 0; i < nchild; i++)
+      {
+!       parse_and_execute (savestring (trap_command), "trap", SEVAL_NOHIST|SEVAL_RESETLINE);
+      }
+  
+--- 4243,4247 ----
+    for (i = 0; i < nchild; i++)
+      {
+!       parse_and_execute (savestring (trap_command), "trap", SEVAL_NOHIST|SEVAL_RESETLINE|SEVAL_NOOPTIMIZE);
+      }
+  
+*** ../bash-5.2-patched/y.tab.c	2022-11-23 17:09:18.000000000 -0500
+--- y.tab.c	2022-11-23 17:21:17.000000000 -0500
+***************
+*** 5139,5143 ****
+      last_lastarg = savestring (last_lastarg);
+  
+!   parse_and_execute (savestring (command), vname, SEVAL_NONINT|SEVAL_NOHIST);
+  
+    restore_parser_state (&ps);
+--- 5154,5158 ----
+      last_lastarg = savestring (last_lastarg);
+  
+!   parse_and_execute (savestring (command), vname, SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOOPTIMIZE);
+  
+    restore_parser_state (&ps);
+*** ../bash-5.2-patched/execute_cmd.c	2022-11-05 17:27:41.000000000 -0400
+--- execute_cmd.c	2022-11-22 17:09:38.000000000 -0500
+***************
+*** 1655,1659 ****
+       and set CMD_TRY_OPTIMIZING for simple commands on the right side of an
+       and-or or `;' list to test for optimizing forks when they are executed. */
+!   if (user_subshell && command->type == cm_subshell)
+      optimize_subshell_command (command->value.Subshell->command);
+  
+--- 1665,1670 ----
+       and set CMD_TRY_OPTIMIZING for simple commands on the right side of an
+       and-or or `;' list to test for optimizing forks when they are executed. */
+!   if (user_subshell && command->type == cm_subshell &&
+!       (command->flags & (CMD_TIME_PIPELINE|CMD_INVERT_RETURN)) == 0)
+      optimize_subshell_command (command->value.Subshell->command);
+  
+*** ../bash-5.2/patchlevel.h	2020-06-22 14:51:03.000000000 -0400
+--- patchlevel.h	2020-10-01 11:01:28.000000000 -0400
+***************
+*** 26,30 ****
+     looks for to find the patch level (for the sccs version string). */
+  
+! #define PATCHLEVEL 14
+  
+  #endif /* _PATCHLEVEL_H_ */
+--- 26,30 ----
+     looks for to find the patch level (for the sccs version string). */
+  
+! #define PATCHLEVEL 15
+  
+  #endif /* _PATCHLEVEL_H_ */