Subject: ksh -p -------- > I'm seeing a bug in ksh93 when run with rgid != egid (and ruid==0), > where rgid is being set inappropriately and changing as a side effect of > a simple test of file mode. > > The result is that issetugid() returns 0 when it should not, which > causes resolution of $ORIGIN in RPATH to succeed, which is a security > violation (see ld.so.1(1)), until a file mode is tested at which point > rgid reverts to its correct value and issetugid starts correctly > returning 1 and $ORIGIN to stop being resolved. > > I've attached a simple ksh script to demonstrate the basic problem > (Test.ksh), as well as a 1-line C application to report issetugid() > (tstissetugid.c), and the script output (test.out). > > The script can be executed (as root) as follows: > # perl -e ' $( = 10; $) = "50 10"; ($(, $)) = (10, 50) ; ; system > "pcred", $$; system "ksh93", "-p", "/tmp/Test.ksh"' > > In the test.out file, you can see that simply executing "[ -r > /etc/shadow ]" causes rgid to change its value. > > Strangely, if you create a shell script that simply says "exec > /tmp/Test.ksh" and execute *it*, the problem is not seen. > > I've reproduced this on OpenSolaris using build 109 (as well as 101b_rc2). > > Before filing a bug I thought I'd run this by the list to see if anyone > has anything to add/contribute. > > Casper Dik has the following to contribute: > > Ah, so what happens is that ksh93 calls setgid(50); unfortunately, when > > you're root, setgid doesn't just change the real gid; it changes all the > > gids > (strange, but true). > > > > Later, it does "setregid(50, 10); access("/etc/shadow"); setregid(10, 50)" > > and suddenly you have an rgid of 10: > > > <snip> > > I think ksh93 shouldn't play with gid/uid. Or sh did that, our ksh didn't. > > > > If we want to change this in ksh93, then we need to change the call > > to setgid() to setregid(). > > > > -Bob > > > #!/bin/ksh -p > exec >/tmp/test.out 2>&1 > set -x > > echo in main > /tmp/tstissetugid > > pcred $$ > [ -r /etc/shadow ] > > pcred $$ > echo in main 2 > /tmp/tstissetugid >
First of all, based on what you are reporting I assume that ksh93 was compiled with SHOPT_P_UID set to a numerical value. Am I correct about this? When SHOPT_P_UID is defined, and the shell is invoked without -p, and the real and effective user id are not the same, and the real user id is greater than the value of SHOPT_P_UID, ksh is supposed to reset the effective user id and group id to the real user and group id. This is done to prevent C programs that are running with an effective user id different from the real uid from calling system() and having the command run by system() run with privilege. If you want to preserve the privilege, you need to run ksh -p. If SHOPT_P_UID is undefined at compilation or if the real user id is less than SHOPT_P_UID, the effective user id should not be changed and the -p option is enabled even if the shell was not invoked with -p. That is how is should have worked. However, there is a bug and the check of the real user id against SHOPT_P_UID was reversed so that real user ids less than SHOPT_P_UID were resetting the effective user and group id. We didn't detect this bug since we have been building with SHOPT_P_UID undefined. David Korn dgk at research.att.com