[PATCH] posix: Fix some null deferences in wordexp [BZ #18096]

Julian Squires julian@cipht.net
Sat Mar 18 12:59:50 GMT 2023


Without these fixes, the first three included tests segfault (on a
NULL dereference); the third aborts on an assertion.

Signed-off-by: Julian Squires <julian@cipht.net>
---
I wasn't aware of the long-languishing issue in Bugzilla before
starting this, which largely includes the same changes, but perhaps
supplying this with test cases will help it be adopted.  Despite the
security exception for wordexp, it still seems reasonable not to crash
in these cases.

 posix/wordexp-test.c |  4 ++++
 posix/wordexp.c      | 12 ++++++------
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/posix/wordexp-test.c b/posix/wordexp-test.c
index f7a591149b..bae27d6cee 100644
--- a/posix/wordexp-test.c
+++ b/posix/wordexp-test.c
@@ -117,6 +117,8 @@ struct test_case_struct
     { 0, NULL, "$((010+0x10))", 0, 1, { "24" }, IFS },
     { 0, NULL, "$((-010+0x10))", 0, 1, { "8" }, IFS },
     { 0, NULL, "$((-0x10+010))", 0, 1, { "-8" }, IFS },
+    { 0, NULL, "$(())", 0, 1, { "0", }, IFS },
+    { 0, NULL, "$[]", 0, 1, { "0", }, IFS },
 
     /* Advanced parameter expansion */
     { 0, NULL, "${var:-bar}", 0, 1, { "bar", }, IFS },
@@ -138,6 +140,8 @@ struct test_case_struct
     { 0, "12345", "${#var}", 0, 1, { "5", }, IFS },
     { 0, NULL, "${var:-'}'}", 0, 1, { "}", }, IFS },
     { 0, NULL, "${var-}", 0, 0, { NULL }, IFS },
+    { 0, NULL, "${a?}", 0, 0, { NULL, }, IFS },
+    { 0, NULL, "${#a=}", 0, 1, { "0", }, IFS },
 
     { 0, "pizza", "${var#${var}}", 0, 0, { NULL }, IFS },
     { 0, "pepperoni", "${var%$(echo oni)}", 0, 1, { "pepper" }, IFS },
diff --git a/posix/wordexp.c b/posix/wordexp.c
index 0da98f5b08..287bb05feb 100644
--- a/posix/wordexp.c
+++ b/posix/wordexp.c
@@ -720,7 +720,7 @@ parse_arith (char **word, size_t *word_length, size_t *max_length,
 	      ++(*offset);
 
 	      /* Go - evaluate. */
-	      if (*expr && eval_expr (expr, &numresult) != 0)
+	      if (expr && eval_expr (expr, &numresult) != 0)
 		{
 		  free (expr);
 		  return WRDE_SYNTAX;
@@ -758,7 +758,7 @@ parse_arith (char **word, size_t *word_length, size_t *max_length,
 	      long int numresult = 0;
 
 	      /* Go - evaluate. */
-	      if (*expr && eval_expr (expr, &numresult) != 0)
+	      if (expr && eval_expr (expr, &numresult) != 0)
 		{
 		  free (expr);
 		  return WRDE_SYNTAX;
@@ -1790,7 +1790,7 @@ envsubst:
 	    {
 	      const char *str = pattern;
 
-	      if (str[0] == '\0')
+	      if (!str || str[0] == '\0')
 		str = _("parameter null or not set");
 
 	      __fxprintf (NULL, "%s: %s\n", env, str);
@@ -1813,7 +1813,7 @@ envsubst:
 	    goto success;
 
 	  value = pattern ? __strdup (pattern) : pattern;
-	  free_value = 1;
+	  free_value = !!pattern;
 
 	  if (pattern && !value)
 	    goto no_space;
@@ -1827,7 +1827,7 @@ envsubst:
 		free (value);
 
 	      value = pattern ? __strdup (pattern) : pattern;
-	      free_value = 1;
+	      free_value = !!pattern;
 
 	      if (pattern && !value)
 		goto no_space;
@@ -1857,7 +1857,7 @@ envsubst:
 	    free (value);
 
 	  value = pattern ? __strdup (pattern) : pattern;
-	  free_value = 1;
+	  free_value = !!pattern;
 
 	  if (pattern && !value)
 	    goto no_space;
-- 
2.39.2



More information about the Libc-alpha mailing list