opendoas

A portable version of the OpenBSD `doas` command
git clone https://pi.duncano.de/git/opendoas.git
Log | Files | Refs | README | LICENSE

commit 9dfca439576c43d28b117abf1bd96db9cc2a8a80
parent fed10b5bab6e9f6b3a06a7b3553dafa6157dce9c
Author: Nathan Holstein <nathan.holstein@gmail.com>
Date:   Wed,  5 Aug 2015 00:38:16 -0400

Fix memory corruption bug in rules parsing.

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.

Diffstat:
doas.c | 8+++++---
parse.y | 14++++++++------
2 files changed, 13 insertions(+), 9 deletions(-)

diff --git 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 @@ -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,