1 The login program (which allows users to gain access to the system) does
2 not handle signals correctly, causing some programs to stay running after
3 the user has logged out.
5 --- util-linux-2.13-pre1/login-utils/login.c.ctty3 2005-08-02 18:10:24.000000000 +0200
6 +++ util-linux-2.13-pre1/login-utils/login.c 2005-08-15 15:51:35.000000000 +0200
8 updwtmp(_PATH_BTMP, &ut);
11 -#endif /* HAVE_SECURITY_PAM_MISC_H */
13 +static int childPid = 0;
14 +static volatile int got_sig = 0;
17 +parent_sig_handler(int signal)
20 + kill(-childPid, signal);
23 + if(signal == SIGTERM)
24 + kill(-childPid, SIGHUP); /* because the shell often ignores SIGTERM */
26 +#endif /* HAVE_SECURITY_PAM_MISC_H */
29 main(int argc, char **argv)
32 pam_handle_t *pamh = NULL;
33 struct pam_conv conv = { misc_conv, NULL };
35 + struct sigaction sa, oldsa_hup, oldsa_term;
39 @@ -1023,7 +1037,18 @@
40 * We must fork before setuid() because we need to call
41 * pam_close_session() as root.
43 + memset(&sa, 0, sizeof(sa));
44 + sa.sa_handler = SIG_IGN;
45 + sigaction(SIGINT, &sa, NULL);
47 + sigaction(SIGHUP, &sa, &oldsa_hup); /* ignore while we detach from the tty */
48 + ioctl(0, TIOCNOTTY, NULL);
50 + sa.sa_handler = parent_sig_handler;
51 + sigaction(SIGHUP, &sa, NULL);
52 + sigaction(SIGTERM, &sa, &oldsa_term);
58 @@ -1034,19 +1059,20 @@
62 - /* parent - wait for child to finish, then cleanup session */
63 - signal(SIGHUP, SIG_IGN);
64 - signal(SIGINT, SIG_IGN);
65 - signal(SIGQUIT, SIG_IGN);
66 - signal(SIGTSTP, SIG_IGN);
67 - signal(SIGTTIN, SIG_IGN);
68 - signal(SIGTTOU, SIG_IGN);
71 + close(0); close(1); close(2);
72 + sa.sa_handler = SIG_IGN;
73 + sigaction(SIGQUIT, &sa, NULL);
74 + sigaction(SIGINT, &sa, NULL);
75 + while(wait(NULL) == -1 && errno == EINTR) /**/ ;
76 + openlog("login", LOG_ODELAY, LOG_AUTHPRIV);
81 + sigaction(SIGHUP, &oldsa_hup, NULL);
82 + sigaction(SIGTERM, &oldsa_term, NULL);
83 + if(got_sig) exit(1);
87 * Problem: if the user's shell is a shell like ash that doesnt do
88 @@ -1058,14 +1084,15 @@
91 /* make sure we have a controlling tty */
93 openlog("login", LOG_ODELAY, LOG_AUTHPRIV); /* reopen */
96 * TIOCSCTTY: steal tty from other process group.
98 - if (ioctl(0, TIOCSCTTY, 1))
99 - syslog(LOG_ERR, _("TIOCSCTTY failed: %m"));
100 + if (ioctl(0, TIOCSCTTY, (char *)1)) {
101 + syslog(LOG_ERR, _("Couldn't set controlling terminal: %s"), strerror(errno));
105 signal(SIGINT, SIG_DFL);