Description of problem:
Programs that run pam as a non-root user, which causes pam_unix to invoke the
unix_chkpwd setuid helper, may fail to be able to verify the password due a
signal handling bug in the PAM module. xscreensaver is one such application.
Version-Release number of selected component (if applicable): 0.75-46.8.0
On my system, it's very reproducible, but reproducibility will vary depending on
a number of factors, especially:
* SMP vs UP
* the kernel's choice of which process to schedule after fork(), and
* the precise details of how SIG_IGN is implemented for SIGCHLD.
I'm currently using kernel 2.5.70.
The problem is in Linux-PAM-0.75/modules/pam_unix/support.c, lines 537-541:
/* save the address of the old SIGCHLD handler, because if the calling
application set a handler, we need to disable it so that we can reap
the helper after it quits */
sighandler = signal(SIGCHLD, SIG_IGN);
The comment is right but the code is wrong. Setting the handler to SIG_IGN
causes the kernel to automatically reap the exit status of /sbin/unix_chkpwd
away, so when the parent calls waitpid, it gets ECHILD.
Really this code shouldn't work at all. I'm guessing that it does only because
the 2.4 kernel returns the status from waitpid despite the setting of SIGCHLD.
Occasionally the code will fail because the child will finish before the parent
To fix, block the signal (eg. with sigprocmask(SIG_BLOCK, ...)) rather than
ignoring the signal.
I am experiencing this bug with an SMP system running the 2.6.0-test2 kernel and
rawhide. The screensaver seems to hang after typing in the password.
I may be experiencing a different bug here. When I added a local passwd account,
unlocking worked fine. It fails with a yp account though. And it continues to
fail with 2.6.0-0.test3.1.31smp.
This is fixed by using SIG_DFL flag instead SIG_IGN in the current
version - pam-0.77-55.