Skip to content

Commit

Permalink
Fix $PWD breakage on fork; cd; exec (rhbz#1168611)
Browse files Browse the repository at this point in the history
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[].
  • Loading branch information
McDutchie committed Sep 26, 2020
1 parent 960a1a9 commit f7c3565
Show file tree
Hide file tree
Showing 3 changed files with 4 additions and 11 deletions.
1 change: 0 additions & 1 deletion src/cmd/ksh93/data/msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 0 additions & 1 deletion src/cmd/ksh93/include/path.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
13 changes: 4 additions & 9 deletions src/cmd/ksh93/sh/path.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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))
{
Expand All @@ -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;
Expand Down

0 comments on commit f7c3565

Please sign in to comment.