From f1627e2a8cc553a8b82147ad192eac8d34885648 Mon Sep 17 00:00:00 2001 From: Johnothan King Date: Sun, 2 Jan 2022 03:59:35 -0800 Subject: [PATCH] Fix typeset -m crash under ASan and on OpenBSD (#412) This fixes the use after free issue that caused typeset -m to crash on older versions of OpenBSD and under ASan. The problem that was causing the failure was that the ap pointer wasn't set to null after the memory associated with it was freed. This commit backports a bugfix from ksh93v- 2013-06-28 that sets ap to null before freeing the associated memory and adds a check that makes sure ap is still a valid pointer before calling array_unscope(). tests/types.sh changes: - Avoid redirecting stderr to /dev/null, as this test shouldn't print anything to stderr. - Apply error message improvement from https://github.com/ksh93/ksh/issues/231#issue-834252084. tests/arrays.sh change: - Apply error message improvement from https://github.com/ksh93/ksh/issues/229#issue-834240645 (re: 7c7fde75). Resolves: https://github.com/ksh93/ksh/issues/231 --- src/cmd/ksh93/sh/array.c | 5 ++++- src/cmd/ksh93/tests/arrays.sh | 3 ++- src/cmd/ksh93/tests/types.sh | 6 +++--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/cmd/ksh93/sh/array.c b/src/cmd/ksh93/sh/array.c index bffaa026f..c6f45361e 100644 --- a/src/cmd/ksh93/sh/array.c +++ b/src/cmd/ksh93/sh/array.c @@ -764,7 +764,10 @@ static void array_putval(Namval_t *np, const char *string, int flags, Namfun_t * free((void*)aq->xp); } if((nfp = nv_disc(np,(Namfun_t*)ap,NV_POP)) && !(nfp->nofree&1)) + { + ap = 0; free((void*)nfp); + } if(!nv_isnull(np)) { if(!np->nvfun) @@ -776,7 +779,7 @@ static void array_putval(Namval_t *np, const char *string, int flags, Namfun_t * if(np->nvalue.cp==Empty) np->nvalue.cp = 0; } - if(!string && (flags&NV_TYPE)) + if(!string && (flags&NV_TYPE) && ap) array_unscope(np,ap); } diff --git a/src/cmd/ksh93/tests/arrays.sh b/src/cmd/ksh93/tests/arrays.sh index 5ca5aa389..1cdf7545e 100755 --- a/src/cmd/ksh93/tests/arrays.sh +++ b/src/cmd/ksh93/tests/arrays.sh @@ -606,7 +606,8 @@ x=$( foo[1]=(x=3) typeset -p foo ) 2> /dev/null -[[ $x == "$exp" ]] || err_exit 'setting element 1 of array to compound variable failed' +[[ $x == "$exp" ]] || err_exit 'setting element 1 of array to compound variable failed' \ + "(expected $(printf %q "$exp"), got $(printf %q "$x"))" # test for cloning a very large indexed array - can core dump ( diff --git a/src/cmd/ksh93/tests/types.sh b/src/cmd/ksh93/tests/types.sh index e88f9db50..d8df9ee7e 100755 --- a/src/cmd/ksh93/tests/types.sh +++ b/src/cmd/ksh93/tests/types.sh @@ -596,10 +596,10 @@ $SHELL << \EOF } main EOF -} 2> /dev/null +} if (( exitval=$?)) -then if [[ $(kill -l $exitval) == SEGV ]] - then err_exit 'typeset -m in type discipline causes exception' +then if ((exitval>128)) + then err_exit "typeset -m in type discipline crashed with SIG$(kill -l $exitval)" else err_exit 'typeset -m in type discipline gives wrong value' fi fi