Skip to content

Commit f7c3565

Browse files
committed
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[].
1 parent 960a1a9 commit f7c3565

3 files changed

Lines changed: 4 additions & 11 deletions

File tree

‎src/cmd/ksh93/data/msg.c‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,6 @@ const char e_suidprofile[] = "/etc/suid_profile";
188188
#if SHOPT_SYSRC
189189
const char e_sysrc[] = "/etc/ksh.kshrc";
190190
#endif
191-
const char e_crondir[] = "/usr/spool/cron/atjobs";
192191
const char e_prohibited[] = "login setuid/setgid shells prohibited";
193192
#ifdef BUILD_DTKSH
194193
const char e_suidexec[] = SUIDEXECPATH;

‎src/cmd/ksh93/include/path.h‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,6 @@ extern const char e_mailmsg[];
117117
extern const char e_suidprofile[];
118118
extern const char e_sysprofile[];
119119
extern const char e_traceprompt[];
120-
extern const char e_crondir[];
121120
#if SHOPT_SUID_EXEC
122121
extern const char e_suidexec[];
123122
#endif /* SHOPT_SUID_EXEC */

‎src/cmd/ksh93/sh/path.c‎

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -236,14 +236,14 @@ static pid_t path_xargs(Shell_t *shp,const char *path, char *argv[],char *const
236236
/*
237237
* make sure PWD is set up correctly
238238
* Return the present working directory
239-
* Invokes getcwd() if flag==0 and if necessary
239+
* Invokes getcwd() if necessary
240240
* Sets the PWD variable to this value
241241
*/
242242
char *path_pwd(Shell_t *shp,int flag)
243243
{
244244
register char *cp;
245-
register char *dfault = (char*)e_dot;
246245
register int count = 0;
246+
NOT_USED(flag);
247247
if(shp->pwd)
248248
return((char*)shp->pwd);
249249
while(1)
@@ -261,11 +261,6 @@ char *path_pwd(Shell_t *shp,int flag)
261261
cp = "/";
262262
break;
263263
case 3:
264-
cp = (char*)e_crondir;
265-
if(flag) /* skip next case when non-zero flag */
266-
++count;
267-
break;
268-
case 4:
269264
{
270265
if(cp=getcwd(NIL(char*),0))
271266
{
@@ -276,8 +271,8 @@ char *path_pwd(Shell_t *shp,int flag)
276271
}
277272
break;
278273
}
279-
case 5:
280-
return(dfault);
274+
case 4:
275+
return((char*)e_dot);
281276
}
282277
if(cp && *cp=='/' && test_inode(cp,e_dot))
283278
break;

0 commit comments

Comments
 (0)