From f7c3565f4eed029163c8959ad8e44767224b3c9c Mon Sep 17 00:00:00 2001 From: Martijn Dekker Date: Sat, 26 Sep 2020 22:31:14 +0200 Subject: [PATCH] Fix $PWD breakage on fork; cd; exec (rhbz#1168611) This applies the following Red Hat patch: https://src.fedoraproject.org/rpms/ksh/blob/642af4d6/f/ksh-20120801-cdfork.patch The associated bug report is public, but nearly all info (such as a reproducer) has been wiped: https://bugzilla.redhat.com/1168611 However, the errata blurb is mildly informative: "Previously, ksh sometimes incorrectly initialized a variable holding the path of the working directory. If a program changed the working directory between forking and ksh execution, then ksh could contain an incorrect value in the working directory variable. With this update, initialization of the working directory variable has been corrected, and ksh now contains the correct value in the aforementioned situation." Also, the patch makes a lot of sense on the face of it. It removes an optimisation in path_pwd() that checks for the directory defined by e_crondir[] in data/msg.c, which is: const char e_crondir[] = "/usr/spool/cron/atjobs"; Of /usr/spool not existed on any system for decades as it is common to mount usr as read-only, so all the writable stuff was moved to /var. So that would never check out. And if 'flag' is nonzero, the optimizing 'count++' is executed regardless of whether that directory exists, ensuring that it never gets the real PWD and defaults to returning ".". src/cmd/ksh93/sh/path.c: - Apply patch as described. - Mark 'flag' variable as NOT_USED to suppress compiler warning. Keep it for backwards compat, as some programs that link with libshell might use this function (though it's undocumented). src/cmd/ksh93/include/path.h, src/cmd/ksh93/data/msg.c: - Remove now-unused e_crondir[]. --- src/cmd/ksh93/data/msg.c | 1 - src/cmd/ksh93/include/path.h | 1 - src/cmd/ksh93/sh/path.c | 13 ++++--------- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/cmd/ksh93/data/msg.c b/src/cmd/ksh93/data/msg.c index 99268bfc7c06..0d0e9c5eae52 100644 --- a/src/cmd/ksh93/data/msg.c +++ b/src/cmd/ksh93/data/msg.c @@ -188,7 +188,6 @@ const char e_suidprofile[] = "/etc/suid_profile"; #if SHOPT_SYSRC const char e_sysrc[] = "/etc/ksh.kshrc"; #endif -const char e_crondir[] = "/usr/spool/cron/atjobs"; const char e_prohibited[] = "login setuid/setgid shells prohibited"; #ifdef BUILD_DTKSH const char e_suidexec[] = SUIDEXECPATH; diff --git a/src/cmd/ksh93/include/path.h b/src/cmd/ksh93/include/path.h index 1ddfe093e4fb..a94c8836a289 100644 --- a/src/cmd/ksh93/include/path.h +++ b/src/cmd/ksh93/include/path.h @@ -117,7 +117,6 @@ extern const char e_mailmsg[]; extern const char e_suidprofile[]; extern const char e_sysprofile[]; extern const char e_traceprompt[]; -extern const char e_crondir[]; #if SHOPT_SUID_EXEC extern const char e_suidexec[]; #endif /* SHOPT_SUID_EXEC */ diff --git a/src/cmd/ksh93/sh/path.c b/src/cmd/ksh93/sh/path.c index d3ede39bce2d..13c1ec4ecbb5 100644 --- a/src/cmd/ksh93/sh/path.c +++ b/src/cmd/ksh93/sh/path.c @@ -236,14 +236,14 @@ static pid_t path_xargs(Shell_t *shp,const char *path, char *argv[],char *const /* * make sure PWD is set up correctly * Return the present working directory - * Invokes getcwd() if flag==0 and if necessary + * Invokes getcwd() if necessary * Sets the PWD variable to this value */ char *path_pwd(Shell_t *shp,int flag) { register char *cp; - register char *dfault = (char*)e_dot; register int count = 0; + NOT_USED(flag); if(shp->pwd) return((char*)shp->pwd); while(1) @@ -261,11 +261,6 @@ char *path_pwd(Shell_t *shp,int flag) cp = "/"; break; case 3: - cp = (char*)e_crondir; - if(flag) /* skip next case when non-zero flag */ - ++count; - break; - case 4: { if(cp=getcwd(NIL(char*),0)) { @@ -276,8 +271,8 @@ char *path_pwd(Shell_t *shp,int flag) } break; } - case 5: - return(dfault); + case 4: + return((char*)e_dot); } if(cp && *cp=='/' && test_inode(cp,e_dot)) break;