1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00
cde/src
Martijn Dekker cd0638690c 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
2022-08-06 11:54:33 +01:00
..
cmd Fix crashes on redefining/unsetting predefined alias (re: 7e7f1372) 2022-08-06 11:54:33 +01:00
lib Fix crashes on redefining/unsetting predefined alias (re: 7e7f1372) 2022-08-06 11:54:33 +01:00
Mamfile More misc. tweaks and cleanups 2022-07-14 17:34:08 +02:00