mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Fix crashes on redefining/unsetting predefined alias (re: 7e7f1372)
Reproducer 1:
$ alias r
r='hist -s'
$ alias r=foo
$ unalias r
ksh(10127,0x10d6c35c0) malloc: *** error for object 0x7ffdcd404468: pointer being freed was not allocated
ksh(10127,0x10d6c35c0) malloc: *** set a breakpoint in malloc_error_break to debug
Abort
The crash happens as unall() (typeset.c) calls nv_delete() (name.c)
which tries to free a node pointer that was not directly allocated.
Reproducer 2:
$ ENV=/./dev/null ksh
$ echo : >script
$ chmod +x script
$ alias r=foo
$ ./script
ksh(10193,0x10c8505c0) malloc: *** error for object 0x7fa136c04468: pointer being freed was not allocated
ksh(10193,0x10c8505c0) malloc: *** set a breakpoint in malloc_error_break to debug
Abort
This crash happens for the same reason, but in another location,
namely in sh_reinit() (init.c) as it is freeing up the alias table
before executing a script that does not start with a #! path.
This is a serious bug because it is not uncommon for .kshrc or
.profile scripts to (re)define an alias called 'r'.
Analysis:
These crashes happen because the incorrectly freed node pointer is
part of a larger block of nodes initialised by sh_inittree() in
init.c. That function allocates all the nodes for a table (see
data/{aliases,builtins,variables}.c) in a contiguous block
addressable by numeric index (see builtins.h and variables.h for
how that is used).
So, while the value of the alias is correctly marked NV_NOFREE and
is not freed, that attribute does not apply to the node pointer
itself, which also is not freeable. Thus, if the value is replaced
by a freeable one, the node pointer is incorrectly freed upon
unaliasing it, and the shell crashes.
The simplest fix is to allocate each predefined alias node
individually, like any other alias -- because, in fact, we do not
need the predefined alias nodes to be in a contiguous addressable
block; there is nothing that specifically addresses these aliases.
src/cmd/ksh93/sh/main.c: sh_main():
- Instead of calling sh_inittree(), use a dedicated loop to
allocate each predefined alias node individually, making each
node invidually freeable. The value does remain non-freeable,
but the NV_NOFREE attribute correctly takes care of that.
src/cmd/ksh93/bltins/typeset.c:
- Get rid of the incomplete and now unnecessary workarounds in
unall() and sh_reinit().
Thanks to @jghub and @JohnoKing for finding and reporting the bug.
Discussion: https://github.com/ksh93/ksh/discussions/503#discussioncomment-3337172
This commit is contained in:
parent
9c9743998f
commit
cd0638690c
7 changed files with 40 additions and 21 deletions
|
|
@ -17,8 +17,8 @@
|
|||
#include <releaseflags.h>
|
||||
|
||||
#define SH_RELEASE_FORK "93u+m" /* only change if you develop a new ksh93 fork */
|
||||
#define SH_RELEASE_SVER "1.0.1" /* semantic version number: https://semver.org */
|
||||
#define SH_RELEASE_DATE "2022-08-05" /* must be in this format for $((.sh.version)) */
|
||||
#define SH_RELEASE_SVER "1.0.2-alpha" /* semantic version number: https://semver.org */
|
||||
#define SH_RELEASE_DATE "2022-08-06" /* must be in this format for $((.sh.version)) */
|
||||
#define SH_RELEASE_CPYR "(c) 2020-2022 Contributors to ksh " SH_RELEASE_FORK
|
||||
|
||||
/* Scripts sometimes field-split ${.sh.version}, so don't change amount of whitespace. */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue