Skip to content

Commit

Permalink
Scope variables to subshell before setting their discipline (#811)
Browse files Browse the repository at this point in the history
Currently, running the tilde.sh tests under ASan will fail with a
use after free.

The crash occurs because the discipline function is assigned before
.sh.tilde is scoped to the currently active virtual subshell. After
this, sh_subshell() frees the discipline function by calling
nv_delete() upon subshell completion, but because of improper
scoping, .sh.tilde in the parent subshell now has an np->nvfun
which points to freed memory. (As a side note, I'll note that this
bug can be reproduced for any variable assigned a discipline
function, not just .sh.tilde.)

src/cmd/ksh93/sh/xec.c: sh_exec():
- Use sh_assignok to scope variables to subshells before assigning
  a new discipline function to them.
  • Loading branch information
JohnoKing authored Jan 5, 2025
1 parent b711e5d commit cbdb8bc
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 1 deletion.
7 changes: 7 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@ This documents significant changes in the dev branch of ksh 93u+m.
For full details, see the git log at: https://github.com/ksh93/ksh
Uppercase BUG_* IDs are shell bug IDs as used by the Modernish shell library.

2025-01-05:

- Fixed a crash that could occur if a discipline function was first assigned
to a variable in a virtual subshell before the variable was scoped to that
subshell, then upon subshell completion another discipline function of the
same type was assigned to that selfsame variable in the parent shell.

2025-01-03:

- The performance of virtual subshells has been significantly improved by
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/ksh93/include/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include <ast_release.h>
#include "git.h"

#define SH_RELEASE_DATE "2025-01-03" /* must be in this format for $((.sh.version)) */
#define SH_RELEASE_DATE "2025-01-05" /* must be in this format for $((.sh.version)) */
/*
* This comment keeps SH_RELEASE_DATE a few lines away from SH_RELEASE_SVER to avoid
* merge conflicts when cherry-picking dev branch commits onto a release branch.
Expand Down
7 changes: 7 additions & 0 deletions src/cmd/ksh93/sh/xec.c
Original file line number Diff line number Diff line change
Expand Up @@ -2382,7 +2382,14 @@ int sh_exec(const Shnode_t *t, int flags)
if(npv)
{
if(!sh.mktype)
{ /*
* Set the discipline function. If this is done in a subshell, the variable
* must be scoped to the subshell before nvfun is set to the discipline.
*/
if(sh.subshell && !sh.subshare)
sh_assignok(npv, 1);
cp = nv_setdisc(npv,cp,np,(Namfun_t*)npv);
}
if(!cp)
{
errormsg(SH_DICT,ERROR_exit(1),e_baddisc,fname);
Expand Down

0 comments on commit cbdb8bc

Please sign in to comment.