Bug 672320 - su returns zero rc when subshell is killed
Summary: su returns zero rc when subshell is killed
Keywords:
Status: CLOSED DUPLICATE of bug 559098
Alias: None
Product: Red Hat Enterprise Linux 5
Classification: Red Hat
Component: coreutils
Version: 5.6
Hardware: Unspecified
OS: Unspecified
medium
medium
Target Milestone: rc
: ---
Assignee: Ondrej Vasik
QA Contact: qe-baseos-daemons
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2011-01-24 20:11 UTC by Joseph Kachuck
Modified: 2018-11-14 14:58 UTC (History)
2 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2011-01-25 06:02:30 UTC
Target Upstream Version:


Attachments (Terms of Use)
coreutils-su-child-killed-status.patch (576 bytes, application/octet-stream)
2011-01-24 20:11 UTC, Joseph Kachuck
no flags Details

Description Joseph Kachuck 2011-01-24 20:11:34 UTC
Created attachment 475034 [details]
coreutils-su-child-killed-status.patch

---Problem Description---
The rc for "su" is zero when the subshell process is killed by kill -9. This
does not happen in other Linux distro. We expect it to return a non-zero rc.

If we download the coreutils-5.97.tar.gz package from
http://ftp.gnu.org/gnu/coreutils/. and install that, then the su return
non-zero as expected.

Oct 22 16:52:01 yessir rootTest.ksh[2636]: Debugging rc return = 265

Also GNU website documents the propper rc:

http://www.gnu.org/software/coreutils/manual/coreutils.html#su-invocation

Exit status:

125 if su itself fails
126 if subshell is found but cannot be invoked
127 if subshell cannot be found
the exit status of the subshell otherwise

---Steps to Reproduce---
Create these 2 scripts:

rootTest.ksh
#!/bin/ksh -p
su - <instance> -c "./test.ksh"
rc=$?
logger -i -p debug -t $0 "Debugging rc return = $rc"

test.ksh
#!/bin/ksh -p
sleep 3000

Run...


[root@lx252 ~]# ./rootTest.ksh

[root@lx252 ~]# ps -ef | grep test.ksh |grep -v
grep
root 3955 3953 0 13:14 pts/0
00:00:00 su - db2ltuid -c ./test.ksh
db2ltuid 3970 3955 0 13:14 ?
00:00:00 /bin/ksh -p ./test.ksh
[root@lx252 ~]# kill -9 3970

[root@lx252 ~]# cat /var/log/messages |grep Debugging
Oct 21 13:14:54 lx252 ./rootTest.ksh[3953]: Debugging rc return = 0


First of all, the version of the package in RHEL 5.6 remains as coreutils-5.97-23.el5_4.2 and so
the problem is there as well. The Red Hat version adds support for PAM via the coreutils-
pam.patch to the su command which is the major difference. The affected routine is
run_shell() in src/su.c and it looks like the culprit for what you see if this section of code at the
end of that routine:

exit (WEXITSTATUS(status));

The patch added some signal support for job management as well as a waitpid() on the parent
side. However, it looks as if it is incorrectly using WEXITSTATUS() by assuming that the child
exited on its own. It really should have been done something like:

if (WIFEXITED(status))
exit (WEXITSTATUS(status));
else
exit (-1);

That is, calling WEXITSTATUS() is only valid if WIFEXITED() returns TRUE. Otherwise, the child
exited abnormally or terminated unexpectedly.

Now, I did a bit a research as to where the 265 came from when using the mainline su. When
using it, there was no parent after the execve() that calls waitpid so in that case the ksh shell
was the parent. When a child is terminated by a signal, ksh sets the exit code to 256 + signo
which is where the 265 comes from due to the signal being SIGKILL or 9.

I modified the rootTest.ksh to be executed as a Bourne shell script and I get 137 because it
uses 128 + signo for the same thing. So, since the Red Hat code does have a waitpid(), it will
not have the same behaviour either but at least it won't return 0.

I'll send this over to Red Hat for them to review.

Patch to su to check for child terminated by signal

This patch adds the check to ensure that the child exited with exit() before using
WEXITSTATUS(). If it didn't and the child was terminated by a signal, su will now display a
message to stderr that looks something like:

User shell terminated by signal %d.

and exit with -1 where %d is the signal code such as 9 for SIGKILL.

This problem is independent of architecture and can be recreated on RHEL 5.5 and RHEL 5.6.

Comment 1 Ondrej Vasik 2011-01-25 06:02:30 UTC
Thanks for report, patch and detailed analysis, this is duplicate of https://bugzilla.redhat.com/show_bug.cgi?id=559098 . I used the same way as is used in shadow-utils to fix that issue - see https://bugzilla.redhat.com/attachment.cgi?id=390256 . Closing DUPLICATE.

*** This bug has been marked as a duplicate of bug 559098 ***


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