fix segfault when PWD is unset
Resolves: rhbz#2123066
This commit is contained in:
parent
5eddd9579a
commit
32a2e21275
151
ksh-1.0.0-beta.1-unset-PWD-segfault.patch
Normal file
151
ksh-1.0.0-beta.1-unset-PWD-segfault.patch
Normal file
@ -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))
|
8
ksh.spec
8
ksh.spec
@ -8,7 +8,7 @@ URL: http://www.kornshell.com/
|
|||||||
License: EPL-1.0
|
License: EPL-1.0
|
||||||
Epoch: 3
|
Epoch: 3
|
||||||
Version: %{verBetaPrefix}~beta.%{verBetaSuffix}
|
Version: %{verBetaPrefix}~beta.%{verBetaSuffix}
|
||||||
Release: 2%{?dist}
|
Release: 3%{?dist}
|
||||||
Source0: https://github.com/ksh93/%{name}/archive/v%{verBetaFull}/%{name}-%{verBetaFull}.tar.gz
|
Source0: https://github.com/ksh93/%{name}/archive/v%{verBetaFull}/%{name}-%{verBetaFull}.tar.gz
|
||||||
Source1: kshcomp.conf
|
Source1: kshcomp.conf
|
||||||
Source2: kshrc.rhs
|
Source2: kshrc.rhs
|
||||||
@ -16,6 +16,8 @@ Source3: dotkshrc
|
|||||||
|
|
||||||
# temporary commenting out failing tests
|
# temporary commenting out failing tests
|
||||||
Patch1: %{name}-%{verBetaFull}-regre-tests.patch
|
Patch1: %{name}-%{verBetaFull}-regre-tests.patch
|
||||||
|
# https://github.com/ksh93/ksh/commit/11177d448dadc7f8300e1db60c4ea5bdd61f13e0
|
||||||
|
Patch2: %{name}-%{verBetaFull}-unset-PWD-segfault.patch
|
||||||
|
|
||||||
Conflicts: pdksh
|
Conflicts: pdksh
|
||||||
Requires: coreutils, diffutils
|
Requires: coreutils, diffutils
|
||||||
@ -141,6 +143,10 @@ fi
|
|||||||
%config(noreplace) %{_sysconfdir}/binfmt.d/kshcomp.conf
|
%config(noreplace) %{_sysconfdir}/binfmt.d/kshcomp.conf
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Jun 27 2023 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.0~beta.1-3
|
||||||
|
- fix segfault when PWD is unset
|
||||||
|
Resolves: #2123066
|
||||||
|
|
||||||
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 3:1.0.0~beta.1-2
|
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 3:1.0.0~beta.1-2
|
||||||
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
|
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
|
||||||
Related: rhbz#1991688
|
Related: rhbz#1991688
|
||||||
|
Loading…
Reference in New Issue
Block a user