From ff358f3464bce5a2ec18e642cf5886afc5259f9e Mon Sep 17 00:00:00 2001 From: Johnothan King Date: Mon, 22 Jun 2020 10:11:19 -0700 Subject: [PATCH] Fix a crash when 'kill %%' and 'kill %+' are run (#35) Ksh was trying to use the 'pw' variable as a valid pointer even when it was NULL. This is fixed by doing the error check for 'pw' before doing anything else in 'job_kill'. This bugfix is from Red Hat: https://git.centos.org/rpms/ksh/blob/44e0a643a93492b1f6beebbf6ffcfd453d9ab8f2/f/SOURCES/ksh-20130214-fixkill.patch Fixes #34 --- NEWS | 3 +++ src/cmd/ksh93/include/version.h | 2 +- src/cmd/ksh93/sh/jobs.c | 4 ++-- src/cmd/ksh93/tests/signal.sh | 7 +++++++ 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 77d83415212e..0570f0dc6009 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,9 @@ Any uppercase BUG_* names are modernish shell bug IDs. cmd=stop; $cmd $! will now work. See 'stop --man' and 'suspend --man' for more information. +- Fixed a bug that caused the kill and stop commands to segfault when given + a non-existent job. + 2020-06-20: - Fixed a bug that caused setting the following variables as readonly in diff --git a/src/cmd/ksh93/include/version.h b/src/cmd/ksh93/include/version.h index 669d54756757..e35c845a27fa 100644 --- a/src/cmd/ksh93/include/version.h +++ b/src/cmd/ksh93/include/version.h @@ -17,4 +17,4 @@ * David Korn * * * ***********************************************************************/ -#define SH_RELEASE "93u+m 2020-06-20" +#define SH_RELEASE "93u+m 2020-06-22" diff --git a/src/cmd/ksh93/sh/jobs.c b/src/cmd/ksh93/sh/jobs.c index d9fcf1f2a971..050aac2a55e1 100644 --- a/src/cmd/ksh93/sh/jobs.c +++ b/src/cmd/ksh93/sh/jobs.c @@ -1111,6 +1111,8 @@ static struct process *job_bystring(register char *ajob) int job_kill(register struct process *pw,register int sig) { + if(!pw) + goto error; Shell_t *shp = pw->p_shp; register pid_t pid; register int r; @@ -1122,8 +1124,6 @@ int job_kill(register struct process *pw,register int sig) #endif /* SIGTSTP */ job_lock(); errno = ECHILD; - if(pw==0) - goto error; pid = pw->p_pid; #if SHOPT_COSHELL if(pw->p_cojob) diff --git a/src/cmd/ksh93/tests/signal.sh b/src/cmd/ksh93/tests/signal.sh index dafdefd035a9..9c0b8622344e 100755 --- a/src/cmd/ksh93/tests/signal.sh +++ b/src/cmd/ksh93/tests/signal.sh @@ -460,5 +460,12 @@ then [[ $actual == *Killed*Killed* ]] && msg='ksh killed itself' || msg='unexpec fi let "${actual##*$'\n'} > 128" || err_exit "child process signal did not cause exit status > 128" +# ====== +# Killing a non-existent job shouldn't cause a segfault. Note that `2> /dev/null` has no effect when +# there is a segfault. +$SHELL -c 'kill %% 2> /dev/null'; [[ $? == 1 ]] || err_exit $'`kill` doesn\'t handle a non-existent job correctly when passed \'%%\'' +$SHELL -c 'kill %+ 2> /dev/null'; [[ $? == 1 ]] || err_exit $'`kill` doesn\'t handle a non-existent job correctly when passed \'%+\'' +$SHELL -c 'kill %- 2> /dev/null'; [[ $? == 1 ]] || err_exit $'`kill` doesn\'t handle a non-existent job correctly when passed \'%-\'' + # ====== exit $((Errors<125?Errors:125))