diff --git a/src/cmd/ksh93/include/argnod.h b/src/cmd/ksh93/include/argnod.h index 6c160688c..636e473ba 100644 --- a/src/cmd/ksh93/include/argnod.h +++ b/src/cmd/ksh93/include/argnod.h @@ -53,7 +53,7 @@ struct comnod #define COMSCAN (01<slptr); + /* + * Since we're dealing with a linked list of stacks, slpold may be inside the allocated region + * pointed to by slpold->slptr, meaning the stakdelete() call may invalidate slpold as well as + * slpold->slptr. So if we do 'stakdelete(slpold->slptr); slpold->slptr = NIL(Stak_t*)' as may + * seem obvious, the assignment may be a use-after-free of slpold. Therefore, save the pointer + * value and reset the pointer before closing/freeing the stack. + */ + Stak_t *sp = slpold->slptr; slpold->slptr = NIL(Stak_t*); + stakdelete(sp); } else staklink(slpold->slptr);