RHEL Engineering is moving the tracking of its product development work on RHEL 6 through RHEL 9 to Red Hat Jira (issues.redhat.com). If you're a Red Hat customer, please continue to file support cases via the Red Hat customer portal. If you're not, please head to the "RHEL project" in Red Hat Jira and file new tickets here. Individual Bugzilla bugs in the statuses "NEW", "ASSIGNED", and "POST" are being migrated throughout September 2023. Bugs of Red Hat partners with an assigned Engineering Partner Manager (EPM) are migrated in late September as per pre-agreed dates. Bugs against components "kernel", "kernel-rt", and "kpatch" are only migrated if still in "NEW" or "ASSIGNED". If you cannot log in to RH Jira, please consult article #7032570. That failing, please send an e-mail to the RH Jira admins at rh-issues@redhat.com to troubleshoot your issue as a user management inquiry. The email creates a ServiceNow ticket with Red Hat. Individual Bugzilla bugs that are migrated will be moved to status "CLOSED", resolution "MIGRATED", and set with "MigratedToJIRA" in "Keywords". The link to the successor Jira issue will be found under "Links", have a little "two-footprint" icon next to it, and direct you to the "RHEL project" in Red Hat Jira (issue links are of type "https://issues.redhat.com/browse/RHEL-XXXX", where "X" is a digit). This same link will be available in a blue banner at the top of the page informing you that that bug has been migrated.
Bug 1135573 - ksh: Problem with 'cd' from a forked C program
Summary: ksh: Problem with 'cd' from a forked C program
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: ksh
Version: 7.0
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: rc
: ---
Assignee: Michal Hlavinka
QA Contact: Martin Frodl
URL:
Whiteboard:
Depends On:
Blocks: 1168611
TreeView+ depends on / blocked
 
Reported: 2014-08-29 16:26 UTC by Paulo Andrade
Modified: 2019-09-12 07:59 UTC (History)
3 users (show)

Fixed In Version: ksh-20120801-21.el7
Doc Type: Bug Fix
Doc Text:
Clone Of:
: 1168611 (view as bug list)
Environment:
Last Closed: 2015-03-05 13:41:46 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)
This patch partially corrects the problem (596 bytes, text/plain)
2014-08-29 16:26 UTC, Paulo Andrade
no flags Details
test case tarball (10.00 KB, application/octet-stream)
2014-08-29 16:40 UTC, Paulo Andrade
no flags Details
ksh-20120801-sfdc01181445.patch (1.11 KB, patch)
2014-09-01 19:39 UTC, Paulo Andrade
no flags Details | Diff


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHBA-2015:0300 0 normal SHIPPED_LIVE ksh bug fix update 2015-03-05 17:34:19 UTC

Description Paulo Andrade 2014-08-29 16:26:36 UTC
Created attachment 932743 [details]
This patch partially corrects the problem

ksh has the src/cmd/ksh93/sh/path.c:path_pwd() function that is used to
compute the current directory from different contexts. The function receives
a boolean flag argument that is useful to avoid a getcwd call, and (re)set
the $PWD variable contents (the PWDNOD "object").

  Regardless of the flag argument, if shp->pwd (a "cached" char* known value
of the current directory) is non null, path_pwd() returns it.

  If shp->pwd is null, path_pwd() will enter a loop, and try to resolve the
current path. It will loop up to six times, attempting to avoid a getcwd
call (maybe because it may be too costly in some environment/filesystem)
and/or attempting to avoid the need of change to the PWDNOD value. The loop
is essentially:

	while(1) 
	{
		/* try from lowest to highest */
		switch(count++)
		{
			case 0:
				cp = nv_getval(PWDNOD);
				break;
			case 1:
				cp = nv_getval(HOME);
				break;
			case 2:
				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))
				{  
					nv_offattr(PWDNOD,NV_NOFREE);
					nv_unset(PWDNOD);
					PWDNOD->nvalue.cp = cp;
					goto skip;
				}
				break;
			}
			case 5:
				return(dfault);
		}
		if(cp && *cp=='/' && test_inode(cp,e_dot))
			break;
	}

   I believe case 3 is history, at least for modern Linux systems, as
it is a hardcoded test of the current directory as /usr/spool/cron/atjobs
that is very likely to always fail. It will only break the loop if
the directory in the cp string pointer has the same stat st_dev and st_ino
as ".". If it loops the six times, it will return ".", that is the
initialized value of "dfault".

  A problem arises here if a C program calls chdir() and then exec*()
ksh, because in that case, (unless doing the noop of chdir()'ing to the
$PWD value), $PWD and "." will not match, it will loop the six times and
return "." as the current directory if receiving a non zero flag (kind
of "fast mode").

  The path_pwd() function is called with a non zero flag argument
during initialization, and only on a few cases will be called with
a zero flag argument, notably when executing a subshell.

  I believe it should be quite safe to remove "case 3" and adjust
the code. Maybe even the flag argument could be ignored, but would
need to check if calling getcwd on a stale nfs could hang, etc,
but that would be the best to ensure path_pwd() actually does what
it advertises (unless shp->pwd somehow is set to a bad value), the
contents of $PWD would always match the current directory; either
the test_inode would validate special values are the same directory,
or call getcwd.

  Nevertheless lets assume we do not want to ignore the flag argument,
because there must be a reason to avoid the getcwd call (possibly a
stale nfs mount, current directory on a tape, etc). *If* if any
*non* builtin command is executed *after* any builtin "cd" call,
(or the builtin "pwd" command is executed, because it calls
path_pwd() with a zero flag) it will call path_pwd() with a zero flag
argument eventually, that would call getcwd() and correct the internal
state. So, my proposed patch is specific to ksh-2012-08-01, because
ksh-2010-06-21 as in earlier rhel is not affected by this issue at least
for the provided test case, but has code quite different, and latest beta,
2014-06-25 also has the code quite different, and *may* not show the
problem, but it was not verified, only base code inspection was done.
So, the patch basically detects the condition where it would get confused,
and corrects it just before the inconsistency happens, that is, while the
input says something like:
	cd ..
ksh would understand it as
	cd .
and do nothing.

Comment 2 Paulo Andrade 2014-08-29 16:40:22 UTC
Created attachment 932746 [details]
test case tarball

This is the test case.

To verify the problem:

$ tar xf CdTest2.tar
$ cd CdTest2
$ ./nmp.sh
PASS
$ gcc tryc.c -o tryc
$ ./tryc
FAIL

The tryc.c source creates the conditions in the bug
description, and the problem with the "cd .." not working
is corrected with the proposed patch.

Comment 3 Paulo Andrade 2014-08-29 16:45:22 UTC
It is important to note that the initial patch is not
fully correct for the test case, because the test case
will still have the incorrect value of $PWD in the line

HOMEWD=$PWD

and the only way to correct that would be to change
src/cmd/ksh93/sh/path.c:path_pwd() to always call
getcwd() if the stat st_dev and st_ino of $PWD do
not match those of ".", but that would basically
throw away the logic in path_pwd() because the check
of $PWD matching "." is the first one.

Comment 4 Paulo Andrade 2014-09-01 19:39:36 UTC
Created attachment 933516 [details]
ksh-20120801-sfdc01181445.patch

This patch corrects the problem by falling back to
calling getcwd if none of the predefined directories
does match ".".

It also removes the check for the at/cron directory.

Comment 9 errata-xmlrpc 2015-03-05 13:41:46 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://rhn.redhat.com/errata/RHBA-2015-0300.html


Note You need to log in before you can comment on or make changes to this bug.