mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-02-15 04:32:24 +00:00
trap: fix use after free (#446)
This commit adds a fix for the trap command, backported from a fork of ksh2020: https://github.com/l0stman/ksh/commit/2033375f src/cmd/ksh93/sh/jobs.c: job_chldtrap(): - Fixed a use after free bug in the for loop. The string pointed to by sh.st.trapcom[SIGCHLD] may be freed from memory after sh_trap(), so it must be reobtained each time sh_trap() is called from within the for loop.
This commit is contained in:
parent
8e72608c1c
commit
fb696ecfae
4 changed files with 14 additions and 5 deletions
5
NEWS
5
NEWS
|
@ -9,6 +9,11 @@ Any uppercase BUG_* names are modernish shell bug IDs.
|
|||
values. Previously, arithmetic $((var=1)) or conditional ${var:=value}
|
||||
assignments were not exported even with allexport on.
|
||||
|
||||
- Fixed a memory leak that could occur when using traps.
|
||||
|
||||
- Fixed a use after free issue that could occur when modifying or setting
|
||||
a SIGCHLD trap.
|
||||
|
||||
2022-02-01:
|
||||
|
||||
- Upon invocation, the interactive shell no longer leaves the user without
|
||||
|
|
|
@ -170,7 +170,7 @@ extern int job_post(pid_t,pid_t);
|
|||
extern void *job_subsave(void);
|
||||
extern void job_subrestore(void*);
|
||||
#if SHOPT_BGX
|
||||
extern void job_chldtrap(const char*,int);
|
||||
extern void job_chldtrap(int);
|
||||
#endif /* SHOPT_BGX */
|
||||
#ifdef JOBS
|
||||
extern void job_init(int);
|
||||
|
|
|
@ -350,6 +350,8 @@ void sh_sigreset(register int mode)
|
|||
}
|
||||
|
||||
}
|
||||
if(sh.st.trapcom[0] && sh.st.trapcom[0] != Empty)
|
||||
free(sh.st.trapcom[0]);
|
||||
sh.st.trapcom[0] = 0;
|
||||
if(mode)
|
||||
sh.st.trapmax = 0;
|
||||
|
@ -411,7 +413,7 @@ void sh_chktrap(void)
|
|||
sh_timetraps();
|
||||
#if SHOPT_BGX
|
||||
if((sh.sigflag[SIGCHLD]&SH_SIGTRAP) && sh.st.trapcom[SIGCHLD])
|
||||
job_chldtrap(sh.st.trapcom[SIGCHLD],1);
|
||||
job_chldtrap(1);
|
||||
#endif /* SHOPT_BGX */
|
||||
while(--sig>=0)
|
||||
{
|
||||
|
|
|
@ -219,7 +219,7 @@ static struct back_save bck;
|
|||
typedef int (*Waitevent_f)(int,long,int);
|
||||
|
||||
#if SHOPT_BGX
|
||||
void job_chldtrap(const char *trap, int unpost)
|
||||
void job_chldtrap(int unpost)
|
||||
{
|
||||
register struct process *pw,*pwnext;
|
||||
pid_t bckpid;
|
||||
|
@ -240,7 +240,9 @@ void job_chldtrap(const char *trap, int unpost)
|
|||
sh.savexit = pw->p_exit;
|
||||
if(pw->p_flag&P_SIGNALLED)
|
||||
sh.savexit |= SH_EXITSIG;
|
||||
sh_trap(trap,0);
|
||||
/* The trap handler for SIGCHLD may change after sh_trap() because of
|
||||
'trap - CHLD', so it's obtained for each iteration of the loop. */
|
||||
sh_trap(sh.st.trapcom[SIGCHLD],0);
|
||||
if(pw->p_pid==bckpid && unpost)
|
||||
job_unpost(pw,0);
|
||||
sh.savexit = oldexit;
|
||||
|
@ -434,7 +436,7 @@ int job_reap(register int sig)
|
|||
{
|
||||
sh.sigflag[SIGCHLD] |= SH_SIGTRAP;
|
||||
if(sig==0)
|
||||
job_chldtrap(sh.st.trapcom[SIGCHLD],0);
|
||||
job_chldtrap(0);
|
||||
else
|
||||
sh.trapnote |= SH_SIGTRAP;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue