From 9c84744c92aa5b4eab6efe5c8828fad0e09aba0c Mon Sep 17 00:00:00 2001 From: Johnothan King Date: Sun, 28 Jun 2020 17:47:08 -0700 Subject: [PATCH] Fix memory corruption when a compound variable is unset The following set of commands ends with a memory fault under certain circumstances because ksh attempts to free memory twice, causing memory corruption: $ testarray=(1 2) $ compound testarray $ unset testarray $ eval testarray= The fix is to make sure 'np->nvfun' is a valid pointer before attempting to free memory in 'put_tree'. This patch is from OpenSUSE: https://build.opensuse.org/package/view_file/shells/ksh/ksh93-nvtree-free.dif?expand=1 src/cmd/ksh93/sh/nvtree.c: - Do not try to free memory when 'np->nvfun' and 'val' are false. src/cmd/ksh93/tests/comvar.sh: - Add a regression test for the double free problem. The reproducer must be run from an executable script with 'ksh -c'. --- NEWS | 3 +++ src/cmd/ksh93/sh/nvtree.c | 2 ++ src/cmd/ksh93/tests/comvar.sh | 24 ++++++++++++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/NEWS b/NEWS index 07f1375a6798..bc42c4e3ffe9 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,9 @@ Any uppercase BUG_* names are modernish shell bug IDs. - Variables created with 'typeset -RF' no longer cause a memory fault when accessed. +- Unsetting an array that was turned into a compound variable will no + longer cause silent memory corruption. + 2020-06-26: - Changing to a directory that has a name starting with a '.' will no diff --git a/src/cmd/ksh93/sh/nvtree.c b/src/cmd/ksh93/sh/nvtree.c index 5b4d5cbd8375..986e8786de6c 100644 --- a/src/cmd/ksh93/sh/nvtree.c +++ b/src/cmd/ksh93/sh/nvtree.c @@ -1142,6 +1142,8 @@ static void put_tree(register Namval_t *np, const char *val, int flags,Namfun_t nv_putv(np, val, flags,fp); if(val && nv_isattr(np,(NV_INTEGER|NV_BINARY))) return; + if(!val && !np->nvfun) + return; if(ap= nv_arrayptr(np)) nleft = array_elem(ap); if(nleft==0) diff --git a/src/cmd/ksh93/tests/comvar.sh b/src/cmd/ksh93/tests/comvar.sh index a2e7b445f862..d751dc4bde7b 100755 --- a/src/cmd/ksh93/tests/comvar.sh +++ b/src/cmd/ksh93/tests/comvar.sh @@ -25,6 +25,15 @@ function err_exit } alias err_exit='err_exit $LINENO' +tmp=$( + d=${TMPDIR:-/tmp}/ksh93.comvar.$$.${RANDOM:-0} + mkdir -m700 -- "$d" && CDPATH= cd -P -- "$d" && pwd +) || { + err\_exit $LINENO 'mkdir failed' + exit 1 +} +trap 'cd / && rm -rf "$tmp"' EXIT + #test for compound variables Command=${0##*/} integer Errors=0 @@ -691,4 +700,19 @@ xx=(foo=bar) xx=() [[ $xx == $'(\n)' ]] || err_exit 'xx=() not unsetting previous value' +# ====== +# Unsetting an array turned into a compound variable shouldn't cause +# memory corruption. This test must be run as an executable script +# with 'ksh -c'. +compound_array=$tmp/compound_array.sh +cat >| "$compound_array" << 'EOF' +testarray=(1 2) +compound testarray +unset testarray +eval testarray= +EOF +chmod +x "$compound_array" +"$SHELL" -c "$compound_array" || err_exit 'unsetting an array turned into a compound variable fails' + +# ====== exit $((Errors<125?Errors:125))