[PATCH] hush: Prevent segfault at unexpected EOF in script.

Dmitry Chestnykh dm.chestnykh at gmail.com
Sat Feb 10 15:51:39 UTC 2024


See https://bugs.buildroot.org/show_bug.cgi?id=15937 .
With this patch the execution of reproducer script
from bugzilla leads to the following output:
'hush: syntax error: unexpected EOF'

Signed-off-by: Dmitry Chestnykh <dm.chestnykh at gmail.com>
---
 shell/hush.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/shell/hush.c b/shell/hush.c
index ca01e2b5b..0595ad592 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -6132,6 +6132,10 @@ static int expand_on_ifs(o_string *output, int n, const char *str)
 
 		if (!*str)  /* EOL - do not finalize word */
 			break;
+
+		if (!G.ifs)
+			return -1;
+
 		word_len = strcspn(str, G.ifs);
 		if (word_len) {
 			/* We have WORD_LEN leading non-IFS chars */
@@ -6598,6 +6602,8 @@ static int append_str_maybe_ifs_split(o_string *output, int n,
 				!!(output->o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
 		if (val && val[0])
 			n = expand_on_ifs(output, n, val);
+		if (n < 0)
+			return n;
 	} else { /* quoted "$VAR" */
 		output->has_quoted_part = 1;
 		debug_printf_expand("quoted '%s', output->o_escape:%d\n", val,
@@ -7129,6 +7135,8 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg)
 			debug_printf_subst("SUBST RES:%d '%s'\n", G.last_exitcode, subst_result.data);
 			n = append_str_maybe_ifs_split(output, n, first_ch, subst_result.data);
 			o_free(&subst_result);
+			if (n < 0)
+				return n;
 			break;
 		}
 #endif
@@ -7215,6 +7223,8 @@ static char **expand_variables(char **argv, unsigned expflags)
 
 		/* expand argv[i] */
 		n = expand_vars_to_list(&output, n, *argv++);
+		if (n < 0)
+			return NULL;
 		/* if (!output->has_empty_slot) -- need this?? */
 			o_addchr(&output, '\0');
 	}
@@ -7605,7 +7615,9 @@ static void parse_and_run_stream(struct in_str *inp, int end_trigger)
 		}
 		debug_print_tree(pipe_list, 0);
 		debug_printf_exec("parse_and_run_stream: run_and_free_list\n");
-		run_and_free_list(pipe_list);
+		if (run_and_free_list(pipe_list) < 0)
+			syntax_error_unexpected_ch(EOF);
+
 		empty = 0;
 		if (G_flag_return_in_progress == 1)
 			break;
@@ -9897,6 +9909,9 @@ static int run_list(struct pipe *pi)
 				/* create list of variable values */
 				debug_print_strings("for_list made from", vals);
 				for_list = expand_strvec_to_strvec(vals);
+				if (for_list == NULL)
+					return -1;
+
 				for_lcur = for_list;
 				debug_print_strings("for_list", for_list);
 			}
-- 
2.43.0



More information about the busybox mailing list