From a0481fcde20d5eaf854b5e340d972ba86b0b3bcc Mon Sep 17 00:00:00 2001 From: eabdullin Date: Thu, 21 Sep 2023 18:57:34 +0000 Subject: [PATCH] import CS ksh-1.0.0~beta.1-3.el9 --- .../ksh-1.0.0-beta.1-unset-PWD-segfault.patch | 151 ++++++++++++++++++ SPECS/ksh.spec | 8 +- 2 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 SOURCES/ksh-1.0.0-beta.1-unset-PWD-segfault.patch diff --git a/SOURCES/ksh-1.0.0-beta.1-unset-PWD-segfault.patch b/SOURCES/ksh-1.0.0-beta.1-unset-PWD-segfault.patch new file mode 100644 index 0000000..9db8293 --- /dev/null +++ b/SOURCES/ksh-1.0.0-beta.1-unset-PWD-segfault.patch @@ -0,0 +1,151 @@ +diff --git a/src/cmd/ksh93/bltins/cd_pwd.c b/src/cmd/ksh93/bltins/cd_pwd.c +index e441805..715171c 100644 +--- a/src/cmd/ksh93/bltins/cd_pwd.c ++++ b/src/cmd/ksh93/bltins/cd_pwd.c +@@ -91,8 +91,6 @@ int b_cd(int argc, char *argv[],Shbltin_t *context) + oldpwd = path_pwd(shp,0); + opwdnod = sh_scoped(shp,OLDPWDNOD); + pwdnod = sh_scoped(shp,PWDNOD); +- if(oldpwd == e_dot && pwdnod->nvalue.cp) +- oldpwd = (char*)pwdnod->nvalue.cp; /* if path_pwd() failed to get the pwd, use $PWD */ + if(shp->subshell) + { + opwdnod = sh_assignok(opwdnod,1); +@@ -116,7 +114,7 @@ int b_cd(int argc, char *argv[],Shbltin_t *context) + if(shp->subshell && !shp->subshare) + { + #if _lib_fchdir +- if(!test_inode(nv_getval(pwdnod),e_dot)) ++ if(!test_inode(shp->pwd,e_dot)) + #endif + sh_subfork(); + } +@@ -221,6 +219,7 @@ success: + if(*dp && (*dp!='.'||dp[1]) && strchr(dir,'/')) + sfputr(sfstdout,dir,'\n'); + nv_putval(opwdnod,oldpwd,NV_RDONLY); ++ free((void*)shp->pwd); + if(*dir == '/') + { + flag = strlen(dir); +@@ -229,16 +228,12 @@ success: + dir[flag] = 0; + nv_putval(pwdnod,dir,NV_RDONLY); + nv_onattr(pwdnod,NV_EXPORT); +- if(shp->pwd) +- free((void*)shp->pwd); +- shp->pwd = sh_strdup(pwdnod->nvalue.cp); ++ shp->pwd = sh_strdup(dir); + } + else + { + /* pathcanon() failed to canonicalize the directory, which happens when 'cd' is invoked from a + nonexistent PWD with a relative path as the argument. Reinitialize $PWD as it will be wrong. */ +- if(shp->pwd) +- free((void*)shp->pwd); + shp->pwd = NIL(const char*); + path_pwd(shp,0); + if(*shp->pwd != '/') +@@ -279,7 +274,7 @@ int b_pwd(int argc, char *argv[],Shbltin_t *context) + errormsg(SH_DICT,ERROR_usage(2),"%s",optusage((char*)0)); + UNREACHABLE(); + } +- if(*(cp = path_pwd(shp,0)) != '/') ++ if(*(cp = path_pwd(shp,0)) != '/' || !test_inode(cp,e_dot)) + { + errormsg(SH_DICT,ERROR_system(1), e_pwd); + UNREACHABLE(); +diff --git a/src/cmd/ksh93/data/msg.c b/src/cmd/ksh93/data/msg.c +index 5cec66d..ee44e81 100644 +--- a/src/cmd/ksh93/data/msg.c ++++ b/src/cmd/ksh93/data/msg.c +@@ -82,7 +82,7 @@ const char e_badpattern[] = "%s: invalid shell pattern"; + const char e_noread[] = "%s: pattern seek requires read access"; + const char e_logout[] = "Use 'exit' to terminate this shell"; + const char e_exec[] = "%s: cannot execute"; +-const char e_pwd[] = "cannot access parent directories"; ++const char e_pwd[] = "determine present working directory"; + const char e_found[] = "%s: not found"; + #ifdef ENAMETOOLONG + const char e_toolong[] = "%s: file name too long"; +diff --git a/src/cmd/ksh93/sh/path.c b/src/cmd/ksh93/sh/path.c +index eb18d8c..c097b5f 100644 +--- a/src/cmd/ksh93/sh/path.c ++++ b/src/cmd/ksh93/sh/path.c +@@ -249,7 +249,12 @@ char *path_pwd(Shell_t *shp,int flag) + NOT_USED(flag); + /* Don't bother if PWD already set */ + if(shp->pwd) +- return((char*)shp->pwd); ++ { ++ if(*shp->pwd=='/') ++ return((char*)shp->pwd); ++ free((void*)shp->pwd); ++ ++ } + /* First see if PWD variable is correct */ + pwdnod = sh_scoped(shp,PWDNOD); + cp = nv_getval(pwdnod); +@@ -261,22 +266,29 @@ char *path_pwd(Shell_t *shp,int flag) + cp = nv_getval(sh_scoped(shp,HOME)); + if(!(cp && *cp=='/' && test_inode(cp,e_dot))) + { +- /* Get physical PWD (no symlinks) using getcwd(3), fall back to "." */ ++ /* Get physical PWD (no symlinks) using getcwd(3) */ + cp = getcwd(NIL(char*),0); +- if(!cp) +- return((char*)e_dot); +- tofree++; ++ if(cp) ++ tofree++; + } + /* Store in PWD variable */ +- if(shp->subshell) +- pwdnod = sh_assignok(pwdnod,1); +- nv_putval(pwdnod,cp,NV_RDONLY); ++ if(cp) ++ { ++ if(shp->subshell) ++ pwdnod = sh_assignok(pwdnod,1); ++ nv_putval(pwdnod,cp,NV_RDONLY); ++ } + if(tofree) +- free(cp); ++ free((void*)cp); + } + nv_onattr(pwdnod,NV_EXPORT); ++ /* Neither obtained the pwd nor can fall back to sane-ish $PWD: fall back to "." */ ++ if(!cp) ++ cp = nv_getval(pwdnod); ++ if(!cp || *cp!='/') ++ nv_putval(pwdnod,cp=(char*)e_dot,NV_RDONLY); + /* Set shell PWD */ +- shp->pwd = sh_strdup(pwdnod->nvalue.cp); ++ shp->pwd = sh_strdup(cp); + return((char*)shp->pwd); + } + +diff --git a/src/cmd/ksh93/tests/path.sh b/src/cmd/ksh93/tests/path.sh +index 4b2a97d..2da7d1f 100755 +--- a/src/cmd/ksh93/tests/path.sh ++++ b/src/cmd/ksh93/tests/path.sh +@@ -902,5 +902,19 @@ got=$? + [[ $exp == $got ]] || err_exit "Test 7E: exit status or error message for exec'd command with long name wrong" \ + "(expected $exp, got $got)" + ++# ====== ++# Crash after unsetting PWD ++(unset PWD; (cd /); :) & # the : avoids optimizing out the subshell ++wait "$!" 2>/dev/null ++((!(e = $?))) || err_exit "shell crashes on 'cd' in subshell exit with unset PWD" \ ++ "(got status $e$( ((e>128)) && print -n /SIG && kill -l "$e"))" ++mkdir "$tmp/testdir" ++cd "$tmp/testdir" ++"$SHELL" -c 'cd /; rmdir "$1"' x "$tmp/testdir" ++(unset PWD; exec "$SHELL" -c '(cd /); :') & ++wait "$!" 2>/dev/null ++((!(e = $?))) || err_exit 'shell crashes on failure obtain the PWD on init' \ ++ "(got status $e$( ((e>128)) && print -n /SIG && kill -l "$e"))" ++ + # ====== + exit $((Errors<125?Errors:125)) diff --git a/SPECS/ksh.spec b/SPECS/ksh.spec index d305d2c..27460c4 100644 --- a/SPECS/ksh.spec +++ b/SPECS/ksh.spec @@ -8,7 +8,7 @@ URL: http://www.kornshell.com/ License: EPL-1.0 Epoch: 3 Version: %{verBetaPrefix}~beta.%{verBetaSuffix} -Release: 2%{?dist} +Release: 3%{?dist} Source0: https://github.com/ksh93/%{name}/archive/v%{verBetaFull}/%{name}-%{verBetaFull}.tar.gz Source1: kshcomp.conf Source2: kshrc.rhs @@ -16,6 +16,8 @@ Source3: dotkshrc # temporary commenting out failing tests Patch1: %{name}-%{verBetaFull}-regre-tests.patch +# https://github.com/ksh93/ksh/commit/11177d448dadc7f8300e1db60c4ea5bdd61f13e0 +Patch2: %{name}-%{verBetaFull}-unset-PWD-segfault.patch Conflicts: pdksh Requires: coreutils, diffutils @@ -141,6 +143,10 @@ fi %config(noreplace) %{_sysconfdir}/binfmt.d/kshcomp.conf %changelog +* Tue Jun 27 2023 Vincent Mihalkovic - 3:1.0.0~beta.1-3 +- fix segfault when PWD is unset + Resolves: #2123066 + * Mon Aug 09 2021 Mohan Boddu - 3:1.0.0~beta.1-2 - Rebuilt for IMA sigs, glibc 2.34, aarch64 flags Related: rhbz#1991688