]> git.armaanb.net Git - opendoas.git/commitdiff
Fix memory corruption bug in rules parsing.
authorNathan Holstein <nathan.holstein@gmail.com>
Wed, 5 Aug 2015 04:38:16 +0000 (00:38 -0400)
committerNathan Holstein <nathan.holstein@gmail.com>
Wed, 5 Aug 2015 12:58:17 +0000 (08:58 -0400)
Various yacc rules for optional configuration items weren't properly
setting the empty items to NULL. As a result, the rules list ends up
with invalid contents, including invalid string pointers.

This bug doesn't occur with OpenBSD's yacc, since it memset()s yyval
upon each reduce. GNU Bison doesn't have the matching memset(), and
thus the difference in behaviors.

doas.c
parse.y

diff --git a/doas.c b/doas.c
index 9384f55417d5b13e454d4bba8f82ac54b8eca514..6fabd7bf1b9887dbf65f1d60f1f8cd906623b455 100644 (file)
--- a/doas.c
+++ b/doas.c
@@ -45,9 +45,11 @@ arraylen(const char **arr)
 {
        size_t cnt = 0;
 
-       while (*arr) {
-               cnt++;
-               arr++;
+       if (arr) {
+               while (*arr) {
+                       cnt++;
+                       arr++;
+               }
        }
        return cnt;
 }
diff --git a/parse.y b/parse.y
index 7b1b45ac84e8249eee46f8caf2e30191432648dc..ef5a3ef7f991bcac9e52390b85aa9062e18439ee 100644 (file)
--- a/parse.y
+++ b/parse.y
@@ -102,8 +102,10 @@ action:            TPERMIT options {
                        $$.action = DENY;
                } ;
 
-options:       /* none */
-               | options option {
+options:       /* none */ {
+                       $$.options = 0;
+                       $$.envlist = NULL;
+               } | options option {
                        $$.options = $1.options | $2.options;
                        $$.envlist = $1.envlist;
                        if ($2.envlist) {
@@ -116,16 +118,17 @@ options:  /* none */
                } ;
 option:                TNOPASS {
                        $$.options = NOPASS;
+                       $$.envlist = NULL;
                } | TKEEPENV {
                        $$.options = KEEPENV;
+                       $$.envlist = NULL;
                } | TKEEPENV '{' envlist '}' {
                        $$.options = KEEPENV;
                        $$.envlist = $3.envlist;
                } ;
 
 envlist:       /* empty */ {
-                       if (!($$.envlist = calloc(1, sizeof(char *))))
-                               errx(1, "can't allocate envlist");
+                       $$.envlist = NULL;
                } | envlist TSTRING {
                        int nenv = arraylen($1.envlist);
                        if (!($$.envlist = reallocarray($1.envlist, nenv + 2,
@@ -161,8 +164,7 @@ args:               /* empty */ {
                } ;
 
 argslist:      /* empty */ {
-                       if (!($$.cmdargs = calloc(1, sizeof(char *))))
-                               errx(1, "can't allocate args");
+                       $$.cmdargs = NULL;
                } | argslist TSTRING {
                        int nargs = arraylen($1.cmdargs);
                        if (!($$.cmdargs = reallocarray($1.cmdargs, nargs + 2,