Skip to content

Commit 10b6ba8

Browse files
authored
Fix memory corruption when a compound variable is unset (#49)
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'.
1 parent 5135cf6 commit 10b6ba8

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ Any uppercase BUG_* names are modernish shell bug IDs.
88
- Variables created with 'typeset -RF' no longer cause a memory fault
99
when accessed.
1010

11+
- Unsetting an array that was turned into a compound variable will no
12+
longer cause silent memory corruption.
13+
1114
2020-06-26:
1215

1316
- Changing to a directory that has a name starting with a '.' will no

src/cmd/ksh93/sh/nvtree.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,6 +1142,8 @@ static void put_tree(register Namval_t *np, const char *val, int flags,Namfun_t
11421142
nv_putv(np, val, flags,fp);
11431143
if(val && nv_isattr(np,(NV_INTEGER|NV_BINARY)))
11441144
return;
1145+
if(!val && !np->nvfun)
1146+
return;
11451147
if(ap= nv_arrayptr(np))
11461148
nleft = array_elem(ap);
11471149
if(nleft==0)

src/cmd/ksh93/tests/comvar.sh

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,15 @@ function err_exit
2525
}
2626
alias err_exit='err_exit $LINENO'
2727

28+
tmp=$(
29+
d=${TMPDIR:-/tmp}/ksh93.comvar.$$.${RANDOM:-0}
30+
mkdir -m700 -- "$d" && CDPATH= cd -P -- "$d" && pwd
31+
) || {
32+
err\_exit $LINENO 'mkdir failed'
33+
exit 1
34+
}
35+
trap 'cd / && rm -rf "$tmp"' EXIT
36+
2837
#test for compound variables
2938
Command=${0##*/}
3039
integer Errors=0
@@ -691,4 +700,23 @@ xx=(foo=bar)
691700
xx=()
692701
[[ $xx == $'(\n)' ]] || err_exit 'xx=() not unsetting previous value'
693702

703+
# ======
704+
# Unsetting an array turned into a compound variable shouldn't cause
705+
# memory corruption. This test must be run as an executable script
706+
# with 'ksh -c' (although that still doesn't make the test very
707+
# consistent as it is testing a heisenbug).
708+
compound_array=$tmp/compound_array.sh
709+
cat >| "$compound_array" << 'EOF'
710+
testarray=(1 2)
711+
compound testarray
712+
unset testarray
713+
eval testarray=
714+
EOF
715+
(
716+
unset LC_ALL # Must be done outside of the script
717+
chmod +x "$compound_array"
718+
"$SHELL" -c "$compound_array"
719+
) || err_exit 'unsetting an array turned into a compound variable fails'
720+
721+
# ======
694722
exit $((Errors<125?Errors:125))

0 commit comments

Comments
 (0)