From 325d73e10760a7917283d7e630974a87c8005bec Mon Sep 17 00:00:00 2001 From: hongjinghao Date: Mon, 4 Dec 2023 19:29:46 +0800 Subject: [PATCH] sync patches from bash community (cherry picked from commit 6c6f6a563bba99de4af22de10db699ceb195a3d2) --- ...n-completing-command-word-with-glob-.patch | 78 ++++++ ...omsub-command-printing-fix-for-crash.patch | 265 ++++++++++++++++++ backport-fix-small-memleak-in-globbing.patch | 28 ++ bash.spec | 8 +- 4 files changed, 378 insertions(+), 1 deletion(-) create mode 100644 backport-fix-for-leak-when-completing-command-word-with-glob-.patch create mode 100644 backport-fix-for-nofork-comsub-command-printing-fix-for-crash.patch create mode 100644 backport-fix-small-memleak-in-globbing.patch diff --git a/backport-fix-for-leak-when-completing-command-word-with-glob-.patch b/backport-fix-for-leak-when-completing-command-word-with-glob-.patch new file mode 100644 index 0000000..8a06e0d --- /dev/null +++ b/backport-fix-for-leak-when-completing-command-word-with-glob-.patch @@ -0,0 +1,78 @@ +From 7f7ee0e9c6766ff5d3de542d03c59590c4a5a44a Mon Sep 17 00:00:00 2001 +From: Chet Ramey +Date: Mon, 17 Jul 2023 17:35:59 -0400 +Subject: [PATCH] fix for leak when completing command word with glob pattern + that matches multiple files; preserve export attribute when unsetting local + variable in case it is reset; fix for using nl_langinfo when performing + charset conversions + +--- + bashline.c | 6 +++++- + lib/sh/unicode.c | 6 +++++- + variables.c | 6 ++++++ + 3 files changed, 16 insertions(+), 2 deletions(-) + +diff --git a/bashline.c b/bashline.c +index c85b05b..2e0c0c7 100644 +--- a/bashline.c ++++ b/bashline.c +@@ -2203,7 +2203,11 @@ globword: + local_index = 0; + + if (glob_matches[1] && rl_completion_type == TAB) /* multiple matches are bad */ +- return ((char *)NULL); ++ { ++ strvec_dispose (glob_matches); ++ glob_matches = (char **)NULL; ++ return ((char *)NULL); ++ } + } + + while (val = glob_matches[local_index++]) +diff --git a/lib/sh/unicode.c b/lib/sh/unicode.c +index d781353..9e3c9da 100644 +--- a/lib/sh/unicode.c ++++ b/lib/sh/unicode.c +@@ -35,6 +35,10 @@ + # include + #endif + ++#if HAVE_LANGINFO_CODESET ++# include ++#endif ++ + #include + + #ifndef USHORT_MAX +@@ -277,7 +281,7 @@ u32cconv (c, s) + { + #if HAVE_LOCALE_CHARSET + charset = locale_charset (); +-#elif HAVE_NL_LANGINFO ++#elif HAVE_LANGINFO_CODESET + charset = nl_langinfo (CODESET); + #else + charset = stub_charset (); +diff --git a/variables.c b/variables.c +index 1a0c2c4..f08575a 100644 +--- a/variables.c ++++ b/variables.c +@@ -4016,10 +4016,16 @@ makunbound (name, vc) + FREE (nameref_cell (old_var)); + else + FREE (value_cell (old_var)); ++#if 0 + /* Reset the attributes. Preserve the export attribute if the variable + came from a temporary environment. Make sure it stays local, and + make it invisible. */ + old_var->attributes = (exported_p (old_var) && tempvar_p (old_var)) ? att_exported : 0; ++#else /* TAG:bash-5.3 look at this again */ ++ /* Reset the attributes, but preserve the export attribute. ++ Make sure it stays local, and make it invisible. */ ++ old_var->attributes = exported_p (old_var) ? att_exported : 0; ++#endif + VSETATTR (old_var, att_local); + VSETATTR (old_var, att_invisible); + var_setvalue (old_var, (char *)NULL); +-- +2.33.0 diff --git a/backport-fix-for-nofork-comsub-command-printing-fix-for-crash.patch b/backport-fix-for-nofork-comsub-command-printing-fix-for-crash.patch new file mode 100644 index 0000000..5cfffda --- /dev/null +++ b/backport-fix-for-nofork-comsub-command-printing-fix-for-crash.patch @@ -0,0 +1,265 @@ +From 4e4cebb6dcf4522243b5b9e87918789aea8f73a1 Mon Sep 17 00:00:00 2001 +From: Chet Ramey +Date: Tue, 20 Jun 2023 11:10:39 -0400 +Subject: [PATCH] fix for nofork comsub command printing; fix for crash caused + by tempvar assignment converted to an array in a function + +--- + arrayfunc.c | 13 ++++++++++ + arrayfunc.h | 2 ++ + builtins/declare.def | 13 +++++++--- + print_cmd.c | 12 +++++---- + shell.h | 2 ++ + subst.h | 1 + + variables.c | 59 ++++++++++++++++++++++++++++++-------------- + 7 files changed, 74 insertions(+), 28 deletions(-) + +diff --git a/arrayfunc.c b/arrayfunc.c +index e4ae34d..44b051e 100644 +--- a/arrayfunc.c ++++ b/arrayfunc.c +@@ -137,6 +137,19 @@ convert_var_to_assoc (var) + return var; + } + ++/* Copy the array (ARRAY *) or assoc (HASH_TABLE *) from variable V1 to V2, ++ and return V2. */ ++SHELL_VAR * ++arrayvar_copyval (SHELL_VAR *v1, SHELL_VAR *v2) ++{ ++ FREE (value_cell (v2)); ++ if (array_p (v1)) ++ var_setarray (v2, array_copy (array_cell (v1))); ++ else if (assoc_p (v1)) ++ var_setassoc (v2, assoc_copy (assoc_cell (v1))); ++ return v2; ++} ++ + char * + make_array_variable_value (entry, ind, key, value, flags) + SHELL_VAR *entry; +diff --git a/arrayfunc.h b/arrayfunc.h +index cd51ee0..27d8579 100644 +--- a/arrayfunc.h ++++ b/arrayfunc.h +@@ -47,6 +47,8 @@ extern int array_expand_once; + extern SHELL_VAR *convert_var_to_array __P((SHELL_VAR *)); + extern SHELL_VAR *convert_var_to_assoc __P((SHELL_VAR *)); + ++extern SHELL_VAR *arrayvar_copyval (SHELL_VAR *, SHELL_VAR *); ++ + extern char *make_array_variable_value __P((SHELL_VAR *, arrayind_t, char *, char *, int)); + + extern SHELL_VAR *bind_array_variable __P((char *, arrayind_t, char *, int)); +diff --git a/builtins/declare.def b/builtins/declare.def +index 7eac6f5..97c8efc 100644 +--- a/builtins/declare.def ++++ b/builtins/declare.def +@@ -952,20 +952,25 @@ restart_new_var_name: + if ((flags_on & (att_exported|att_readonly)) && tempvar_p (var)) + { + SHELL_VAR *tv; +- char *tvalue; + + tv = find_tempenv_variable (var->name); + if (tv) + { +- tvalue = var_isset (var) ? savestring (value_cell (var)) : savestring (""); +- tv = bind_variable (var->name, tvalue, 0); ++ /* We don't bother with modifying the temporary env because ++ we're already using it. */ ++ tv = bind_variable (name_cell (var), value_cell (var), ASS_NOTEMPENV); + if (tv) + { ++#if defined (ARRAY_VARS) ++ /* copy array value if array variable */ ++ if ((array_p (var) || assoc_p (var))) ++ arrayvar_copyval (var, tv); ++#endif ++ /* then copy attributes */ + tv->attributes |= var->attributes & ~att_tempvar; + if (tv->context > 0) + VSETATTR (tv, att_propagate); + } +- free (tvalue); + } + VSETATTR (var, att_propagate); + } +diff --git a/print_cmd.c b/print_cmd.c +index 9aa6557..6607993 100644 +--- a/print_cmd.c ++++ b/print_cmd.c +@@ -666,7 +666,7 @@ print_group_command (group_command) + group_command_nesting++; + cprintf ("{ "); + +- if (inside_function_def == 0) ++ if (inside_function_def == 0 /* && pretty_print_mode == 0 */) + skip_this_indent++; + else + { +@@ -680,7 +680,7 @@ print_group_command (group_command) + make_command_string_internal (group_command->command); + PRINT_DEFERRED_HEREDOCS (""); + +- if (inside_function_def) ++ if (inside_function_def /* || pretty_print_mode */) + { + cprintf ("\n"); + indentation -= indentation_amount; +@@ -1459,9 +1459,11 @@ indent (amount) + static void + semicolon () + { +- if (command_string_index > 0 && +- (the_printed_command[command_string_index - 1] == '&' || +- the_printed_command[command_string_index - 1] == '\n')) ++ if ((command_string_index > 0 && ++ the_printed_command[command_string_index - 1] == '\n') || ++ (command_string_index > 1 && ++ the_printed_command[command_string_index - 1] == '&' && ++ the_printed_command[command_string_index - 2] == ' ')) + return; + cprintf (";"); + } +diff --git a/shell.h b/shell.h +index 8072605..fef9347 100644 +--- a/shell.h ++++ b/shell.h +@@ -106,6 +106,8 @@ extern int indirection_level; + extern int shell_compatibility_level; + extern int running_under_emacs; + ++extern int pretty_print_mode; ++ + extern int posixly_correct; + extern int no_line_editing; + +diff --git a/subst.h b/subst.h +index faf831b..b161c3c 100644 +--- a/subst.h ++++ b/subst.h +@@ -54,6 +54,7 @@ + #define ASS_NOEXPAND 0x0080 /* don't expand associative array subscripts */ + #define ASS_NOEVAL 0x0100 /* don't evaluate value as expression */ + #define ASS_NOLONGJMP 0x0200 /* don't longjmp on fatal assignment error */ ++#define ASS_NOTEMPENV 0x2000 /* don't assign into temporary environment */ + + /* Flags for the string extraction functions. */ + #define SX_NOALLOC 0x0001 /* just skip; don't return substring */ +diff --git a/variables.c b/variables.c +index 7abd778..21be2cd 100644 +--- a/variables.c ++++ b/variables.c +@@ -259,6 +259,8 @@ static SHELL_VAR *new_shell_variable __P((const char *)); + static SHELL_VAR *make_new_variable __P((const char *, HASH_TABLE *)); + static SHELL_VAR *bind_variable_internal __P((const char *, char *, HASH_TABLE *, int, int)); + ++static void init_shell_variable (SHELL_VAR *); ++ + static void dispose_variable_value __P((SHELL_VAR *)); + static void free_variable_hash_data __P((PTR_T)); + +@@ -2683,6 +2685,21 @@ make_local_variable (name, flags) + new_var = make_new_variable (name, vc->table); + else + { ++#if 0 ++ /* This handles the case where a variable is found in both the temporary ++ environment *and* declared as a local variable. If we want to avoid ++ multiple entries with the same name in VC->table (that might mess up ++ unset), we need to use the existing variable entry and destroy the ++ current value. Currently disabled because it doesn't matter -- the ++ right things happen. */ ++ new_var = 0; ++ if (was_tmpvar && (new_var = hash_lookup (name, vc->table))) ++ { ++ dispose_variable_value (new_var); ++ init_variable (new_var); ++ } ++ if (new_var == 0) ++#endif + new_var = make_new_variable (name, vc->table); + + /* If we found this variable in one of the temporary environments, +@@ -2742,16 +2759,9 @@ set_local_var_flags: + return (new_var); + } + +-/* Create a new shell variable with name NAME. */ +-static SHELL_VAR * +-new_shell_variable (name) +- const char *name; ++static void ++init_variable (SHELL_VAR *entry) + { +- SHELL_VAR *entry; +- +- entry = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR)); +- +- entry->name = savestring (name); + var_setvalue (entry, (char *)NULL); + CLEAR_EXPORTSTR (entry); + +@@ -2764,7 +2774,18 @@ new_shell_variable (name) + make_local_variable has the responsibility of changing the + variable context. */ + entry->context = 0; ++} + ++/* Create a new shell variable with name NAME. */ ++static SHELL_VAR * ++new_shell_variable (const char *name) ++{ ++ SHELL_VAR *entry; ++ ++ entry = (SHELL_VAR *)xmalloc (sizeof (SHELL_VAR)); ++ ++ entry->name = savestring (name); ++ init_variable (entry); + return (entry); + } + +@@ -3233,8 +3254,9 @@ bind_variable (name, value, flags) + and, if found, modify the value there before modifying it in the + shell_variables table. This allows sourced scripts to modify values + given to them in a temporary environment while modifying the variable +- value that the caller sees. */ +- if (temporary_env && value) /* XXX - can value be null here? */ ++ value that the caller sees. The caller can inhibit this by setting ++ ASS_NOTEMPENV in FLAGS. */ ++ if (temporary_env && value && (flags & ASS_NOTEMPENV) == 0) /* XXX - can value be null here? */ + bind_tempenv_variable (name, value); + + /* XXX -- handle local variables here. */ +@@ -4537,6 +4559,11 @@ push_temp_var (data) + + v = bind_variable_internal (var->name, value_cell (var), binding_table, 0, ASS_FORCE|ASS_NOLONGJMP); + ++#if defined (ARRAY_VARS) ++ if (v && (array_p (var) || assoc_p (var))) ++ arrayvar_copyval (var, v); ++#endif ++ + /* XXX - should we set the context here? It shouldn't matter because of how + assign_in_env works, but we do it anyway. */ + if (v) +@@ -5209,14 +5236,8 @@ push_posix_tempvar_internal (var, isbltin) + v->context = shell_variables->scope; + #if defined (ARRAY_VARS) + if (v && (array_p (var) || assoc_p (var))) +- { +- FREE (value_cell (v)); +- if (array_p (var)) +- var_setarray (v, array_copy (array_cell (var))); +- else +- var_setassoc (v, assoc_copy (assoc_cell (var))); +- } +-#endif ++ arrayvar_copyval (var, v); ++#endif + if (shell_variables == global_variables) + var->attributes &= ~(att_tempvar|att_propagate); + else +-- +2.33.0 diff --git a/backport-fix-small-memleak-in-globbing.patch b/backport-fix-small-memleak-in-globbing.patch new file mode 100644 index 0000000..51b5f09 --- /dev/null +++ b/backport-fix-small-memleak-in-globbing.patch @@ -0,0 +1,28 @@ +From 829aad36dbbeee462fa142fe2c571fd7ab735ba8 Mon Sep 17 00:00:00 2001 +From: Chet Ramey +Date: Mon, 26 Jun 2023 17:09:08 -0400 +Subject: [PATCH] backport part of patch to fix small memleak in globbing + +--- + lib/glob/glob.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/lib/glob/glob.c b/lib/glob/glob.c +index b66af85..e4283bd 100644 +--- a/lib/glob/glob.c ++++ b/lib/glob/glob.c +@@ -1446,6 +1446,12 @@ glob_filename (pathname, flags) + free ((char *) array); + else if ((dflags & GX_ALLDIRS) && filename[0] == '*' && filename[1] == '*' && filename[2] == '\0') + free (temp_results); /* expanding ** case above */ ++ else if (array == temp_results) ++ /* If array == temp_results, either we assigned it above or ++ glob_dir_to_array returned temp_results because the dirname ++ was the empty string. In any case, we assume temp_results ++ has not been freed, and free it here. */ ++ free (temp_results); + + if (shouldbreak) + break; +-- +2.33.0 diff --git a/bash.spec b/bash.spec index f79bf67..da34eb3 100644 --- a/bash.spec +++ b/bash.spec @@ -1,6 +1,6 @@ Name: bash Version: 5.0 -Release: 19 +Release: 20 Summary: It is the Bourne Again Shell License: GPLv3 URL: https://www.gnu.org/software/bash @@ -47,6 +47,9 @@ Patch138:enable-dot-logout-and-source-bashrc-through-ssh.patch Patch6001: backport-Bash-5.1-patch-12-fix-race-condition-with-child-proc.patch Patch6002: backport-Bash-5.1-patch-16-fix-interpretation-of-multiple-ins.patch +Patch6003: backport-fix-for-nofork-comsub-command-printing-fix-for-crash.patch +Patch6004: backport-fix-small-memleak-in-globbing.patch +Patch6005: backport-fix-for-leak-when-completing-command-word-with-glob-.patch BuildRequires: gcc bison texinfo autoconf ncurses-devel @@ -133,6 +136,9 @@ make check %exclude %{_infodir}/dir %changelog +* Mon Dec 4 2023 hongjinghao - 5.0-20 +- sync patches from bash community + * Sun Apr 23 2023 wangyuhang - 5.0-19 - Type:bugfix - CVE: -- Gitee