diff --git a/SOURCES/ksh-20120801-jobcontrol.patch b/SOURCES/ksh-20120801-jobcontrol.patch new file mode 100644 index 0000000..903711d --- /dev/null +++ b/SOURCES/ksh-20120801-jobcontrol.patch @@ -0,0 +1,47 @@ +From 27909acb584aed231d757d1d63c6c62b57c8e152 Mon Sep 17 00:00:00 2001 +From: Vincent Mihalkovic +Date: Mon, 3 Jan 2022 14:03:20 +0100 +Subject: [PATCH] Fix race conditions running external commands with job + control on + +When ksh is compiled with SHOPT_SPAWN (the default), which uses +posix_spawn(3) or vfork(2) (via sh_ntfork()) to launch external +commands, at least two race conditions occur when launching +external commands while job control is active. See: +https://bugs.launchpad.net/ubuntu/+source/ksh/+bug/1887863/comments/3 +https://www.mail-archive.com/ast-developers@research.att.com/msg00717.html + +The basic issue is that this performance optimisation is +incompatible with job control, because it uses a spawning mechanism +that doesn't copy the parent process' memory pages into the child +process, therefore no state that involves memory can be set before +exec-ing the external program. This makes it impossible to +correctly set the terminal's process group ID in the child process, +something that is essential for job control to work. + +src/cmd/ksh93/sh/xec.c: +- Use sh_fork() instead of sh_ntfork() if job control is active. + This uses fork(2), which is 30%-ish slower on most sytems, but + allows for correctly setting the terminal process group. + +Fixes: https://github.com/ksh93/ksh/issues/79 +--- + src/cmd/ksh93/sh/xec.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/cmd/ksh93/sh/xec.c b/src/cmd/ksh93/sh/xec.c +index ae13178..be57a6b 100644 +--- a/src/cmd/ksh93/sh/xec.c ++++ b/src/cmd/ksh93/sh/xec.c +@@ -1737,7 +1737,7 @@ int sh_exec(register const Shnode_t *t, int flags) + #else + #if SHOPT_SPAWN + # ifdef _lib_fork +- if(com) ++ if(com && !job.jobcontrol) + parent = sh_ntfork(shp,t,com,&jobid,ntflag); + else + parent = sh_fork(shp,type,&jobid); +-- +2.31.1 + diff --git a/SOURCES/ksh-20120801-stack-robustness-2.patch b/SOURCES/ksh-20120801-stack-robustness-2.patch new file mode 100644 index 0000000..d125f6e --- /dev/null +++ b/SOURCES/ksh-20120801-stack-robustness-2.patch @@ -0,0 +1,12 @@ +diff -up ksh-20120801/src/lib/libast/misc/stk.c.orig ksh-20120801/src/lib/libast/misc/stk.c +--- ksh-20120801/src/lib/libast/misc/stk.c.orig 2022-01-31 16:06:11.923069379 -0300 ++++ ksh-20120801/src/lib/libast/misc/stk.c 2022-01-31 16:06:54.896802455 -0300 +@@ -76,7 +76,7 @@ struct frame + struct stk + { + _stk_overflow_ stkoverflow; /* called when malloc fails */ +- short stkref; /* reference count; */ ++ int stkref; /* reference count; */ + short stkflags; /* stack attributes */ + char *stkbase; /* beginning of current stack frame */ + char *stkend; /* end of current stack frame */ diff --git a/SOURCES/ksh-20120801-stack-robustness.patch b/SOURCES/ksh-20120801-stack-robustness.patch new file mode 100644 index 0000000..e22bee2 --- /dev/null +++ b/SOURCES/ksh-20120801-stack-robustness.patch @@ -0,0 +1,153 @@ +From 4604df9ada906e0a6537157a63b6ce7c0509f34d Mon Sep 17 00:00:00 2001 +From: Martijn Dekker +Date: Thu, 28 Jan 2021 06:08:38 +0000 +Subject: [PATCH] Stack robustness fixes from OpenSUSE + +Three OpenSUSE patches from: +https://build.opensuse.org/package/show/shells/ksh + +As usual, the relevant bug is not currently public: +https://bugzilla.opensuse.org/show_bug.cgi?id=844071 + +src/cmd/ksh93/sh/xec.c: sh_debug()/sh_exec(): +- Fix stk restoration. [bnc#844071] + +src/lib/libast/misc/stk.c: +- Fix stk aliasing code. [bnc#844071] + (ksh93-stkalias.dif) +- Make a unknown location fatal in stkset() so that we get a core + dump right away instead of later in an unrelated part of code. + (ksh93-stkset-abort.dif) + +src/lib/libast/man/stk.3, +src/lib/libast/man/stak.3: +- Update manual with new stkset() behaviour. (93u+m addition) + (Note that stak is implemented as macros that translate to stk) +--- + src/cmd/ksh93/sh/xec.c | 6 +++--- + src/lib/libast/man/stak.3 | 5 +++-- + src/lib/libast/man/stk.3 | 5 +++-- + src/lib/libast/misc/stk.c | 16 ++++++++++------ + 4 files changed, 19 insertions(+), 13 deletions(-) + +diff --git a/src/cmd/ksh93/sh/xec.c b/src/cmd/ksh93/sh/xec.c +index 23526098ec20..ca3876394d63 100644 +--- a/src/cmd/ksh93/sh/xec.c ++++ b/src/cmd/ksh93/sh/xec.c +@@ -646,8 +646,8 @@ int sh_debug(Shell_t *shp, const char *trap, const char *name, const char *subsc + Stk_t *stkp=shp->stk; + struct sh_scoped savst; + Namval_t *np = SH_COMMANDNOD; +- char *sav = stkptr(stkp,0); + int n=4, offset=stktell(stkp); ++ char *sav = stkfreeze(stkp,0); + const char *cp = "+=( "; + Sfio_t *iop = stkstd; + short level; +@@ -702,7 +702,7 @@ int sh_debug(Shell_t *shp, const char *trap, const char *name, const char *subsc + nv_putval(SH_FUNNAMENOD,shp->st.funname,NV_NOFREE); + shp->st = savst; + if(sav != stkptr(stkp,0)) +- stkset(stkp,sav,0); ++ stkset(stkp,sav,offset); + else + stkseek(stkp,offset); + return(n); +@@ -962,7 +962,7 @@ int sh_exec(register const Shnode_t *t, int flags) + int ntflag = 0; + #endif + int topfd = shp->topfd; +- char *sav=stkptr(stkp,0); ++ char *sav=stkfreeze(stkp,0); + char *cp=0, **com=0, *comn; + int argn; + int skipexitset = 0; +diff --git a/src/lib/libast/man/stak.3 b/src/lib/libast/man/stak.3 +index 5feac69..89e0f54 100644 +--- a/src/lib/libast/man/stak.3 ++++ b/src/lib/libast/man/stak.3 +@@ -109,8 +109,9 @@ the given \fIaddress\fP, and sets the current object to the given + \fIaddress\fP. + The top of the current object is set to \fIoffset\fP bytes from + current object. +-If \fIaddress\fP is not the address of an object on the +-stack the result is undefined. ++If \fIaddress\fP is null, the stack is reset to the beginning. ++If it is non-null, but is not the address of an object on the ++stack, the program aborts and dumps core. + .PP + The remaining functions are used to build the current object incrementally. + An object that is built incrementally on the stack will +diff --git a/src/lib/libast/man/stk.3 b/src/lib/libast/man/stk.3 +index 20dfdbefa44c..dd5705cf1188 100644 +--- a/src/lib/libast/man/stk.3 ++++ b/src/lib/libast/man/stk.3 +@@ -110,8 +110,9 @@ the given \fIaddress\fP, and sets the current object to the given + \fIaddress\fP. + The top of the current object is set to \fIoffset\fP bytes from + current object. +-If \fIaddress\fP is not the address of an object on the +-stack the result is undefined. ++If \fIaddress\fP is null, the stack is reset to the beginning. ++If it is non-null, but is not the address of an object on the ++stack, the program aborts and dumps core. + .PP + The \f5sfio\fP(3) output functions can be used to build + current object incrementally. +diff --git a/src/lib/libast/misc/stk.c b/src/lib/libast/misc/stk.c +index 31cd0911dd29..f147ae4fec8c 100644 +--- a/src/lib/libast/misc/stk.c ++++ b/src/lib/libast/misc/stk.c +@@ -331,9 +331,9 @@ int stkon(register Sfio_t * stream, register char* loc) + } + /* + * reset the bottom of the current stack back to +- * if is not in this stack, then the stack is reset to the beginning ++ * if is null, then the stack is reset to the beginning ++ * if is not in this stack, the program dumps core + * otherwise, the top of the stack is set to stkbot+ +- * + */ + char *stkset(register Sfio_t * stream, register char* loc, size_t offset) + { +@@ -377,6 +377,9 @@ char *stkset(register Sfio_t * stream, register char* loc, size_t offset) + break; + frames++; + } ++ /* not found: produce a useful stack trace now instead of a useless one later */ ++ if(loc) ++ abort(); + /* set stack back to the beginning */ + cp = (char*)(fp+1); + if(frames) +@@ -503,7 +506,7 @@ static char *stkgrow(register Sfio_t *stream, size_t size) + register char *cp, *dp=0; + register size_t m = stktell(stream); + size_t endoff; +- char *end=0; ++ char *end=0, *oldbase=0; + int nn=0,add=1; + n += (m + sizeof(struct frame)+1); + if(sp->stkflags&STK_SMALL) +@@ -519,6 +522,7 @@ static char *stkgrow(register Sfio_t *stream, size_t size) + dp=sp->stkbase; + sp->stkbase = ((struct frame*)dp)->prev; + end = fp->end; ++ oldbase = dp; + } + endoff = end - dp; + cp = newof(dp, char, n, nn*sizeof(char*)); +@@ -545,10 +549,10 @@ static char *stkgrow(register Sfio_t *stream, size_t size) + if(fp->nalias=nn) + { + fp->aliases = (char**)fp->end; +- if(end && nn>1) +- memmove(fp->aliases,end,(nn-1)*sizeof(char*)); ++ if(end && nn>add) ++ memmove(fp->aliases,end,(nn-add)*sizeof(char*)); + if(add) +- fp->aliases[nn-1] = dp + roundof(sizeof(struct frame),STK_ALIGN); ++ fp->aliases[nn-1] = oldbase + roundof(sizeof(struct frame),STK_ALIGN); + } + if(m && !dp) + { diff --git a/SPECS/ksh.spec b/SPECS/ksh.spec index 60d9709..5c00740 100644 --- a/SPECS/ksh.spec +++ b/SPECS/ksh.spec @@ -6,7 +6,7 @@ Summary: The Original ATT Korn Shell URL: http://www.kornshell.com/ License: EPL Version: %{releasedate} -Release: 255%{?dist} +Release: 257%{?dist} Source0: http://www.research.att.com/~gsf/download/tgz/ast-ksh.%{release_date}.tgz Source1: http://www.research.att.com/~gsf/download/tgz/INIT.%{release_date}.tgz Source2: kshcomp.conf @@ -217,8 +217,20 @@ Patch88: ksh-20120801-annocheck.patch # rhbz#1790547 Patch89: ksh-20120801-cve-2019-14868.patch -# rhbz#2109589 -Patch90: ksh-20120801-signal-bubbling.patch +# rhbz#1857847 +Patch90: ksh-20120801-jobcontrol.patch + +# rhbz#2060600 +Patch91: ksh-20120801-signal-bubbling.patch + +# rhbz#2116372 +# upstream commit: https://github.com/ksh93/ksh/commit/4604df9ada906e0a6537157a63b6ce7c0509f34d +Patch92: ksh-20120801-stack-robustness.patch + +# rhbz#2116372 +# upstream commit: https://github.com/ksh93/ksh/commit/56805b25af24f454cdd477609bcddc984628bc01 +Patch93: ksh-20120801-stack-robustness-2.patch + Conflicts: pdksh Requires: coreutils, diffutils, chkconfig @@ -372,9 +384,17 @@ fi %config(noreplace) %{_sysconfdir}/binfmt.d/kshcomp.conf %changelog -* Thu Jul 21 2022 Vincent Mihalkovic - 20120801-255 +* Mon Aug 08 2022 Vincent Mihalkovic - 20120801-257 +- Stack robustness fixes (two patches) + Resolves: #2116372 + +* Thu Jul 21 2022 Vincent Mihalkovic - 20120801-256 - Do not evaluate arithmetic expressions from environment variables at startup - Resolves: #2109589 + Resolves: #2060600 + +* Mon Jan 03 2022 Vincent Mihalkovic - 20120801-255 +- Fix race conditions running external commands with job control on + Resolves: #1857847 * Thu Feb 06 2020 Siteshwar Vashisht - 20120801-254 - Bump version number to avoid breaking upgrade path