Hide Forgot
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.
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 ***