Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 13 Jun 2001 14:39:21 -0400
From:      "Alexander N. Kabaev" <ak03@gte.com>
To:        freebsd-audit@FreeBSD.org
Subject:   su/zsh problems, proposed fix
Message-ID:  <20010613143921.A65820@kanpc.gte.com>

next in thread | raw e-mail | index | archive | help

--IJpNTDwzlM2Ie8A6
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

There is a problem with su in -CURRENT when used by the users who have zsh set
as their login shell. zsh never calls setpgrp on startup itself but rather
relies on its parent to do that if so desired. After PAM support has been added
to su in -CURRENT, causing  su to change its previous behavior of doing exec to
run the command to fork+exec+waitpid sequence, running su -m from the command
line results in su and zsh processes both running in the same process group. Now
if user presses ^C on the keyboard, SIGINT signal is dispatched to both su and
zsh processes. zsh runs in interactive mode, so it ignores the signal and
continues to run, while su itself dies.  The parent shell process then detects
su's death and mistakenly tries to regain control over the terminal, conflicting
with the still alive shell which has been previously spawned by su. Failing
that, the parent shell dies abnormally with TTY input/output error message and
takes your xterm/login session/screen window/etc along.

Attached patch attempts to resolve this issue by changing su to ignore SIGINT,
SIGQUIT and SIGTSTP signals while waiting for the child to complete. I have been
running -CURRENT for at least two weeks now with the patch applied and I did not
have any problems with it so far. I submitted this patch to Mark Murray earlier 
today and he did not have problem with it and  he suggested that the patch should
be posted on audit@freebsd.org for further review.

Please let me know if you have any comments or suggestions.

--
Alexander Kabaev
PS. SIGTSTP signal should probably be removed from the list of ignored signals,
I am not even sure how it got there...

--IJpNTDwzlM2Ie8A6
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="su.diff"

Index: su.c
===================================================================
RCS file: /usr/ncvs/src/usr.bin/su/su.c,v
retrieving revision 1.39
diff -u -u -r1.39 su.c
--- su.c	2001/05/26 09:52:36	1.39
+++ su.c	2001/06/12 20:55:03
@@ -123,6 +123,7 @@
 	char		*p, *user, *shell, *username, *cleanenv, **nargv, **np,
 			*class, *mytty, shellbuf[MAXPATHLEN],
 			myhost[MAXHOSTNAMELEN + 1];
+	struct sigaction sa, sa_int, sa_quit, sa_tstp;
 
 	shell = class = cleanenv = NULL;
 	asme = asthem = fastlogin = statusp = 0;
@@ -307,6 +308,12 @@
 	 * We must fork() before setuid() because we need to call
 	 * pam_setcred(pamh, PAM_DELETE_CRED) as root.
 	 */
+	sa.sa_flags = SA_RESTART;
+	sa.__sigaction_u.__sa_handler = SIG_IGN;
+	sigemptyset(&sa.sa_mask);
+	sigaction(SIGINT, &sa, &sa_int);
+	sigaction(SIGQUIT, &sa, &sa_quit);
+	sigaction(SIGTSTP, &sa, &sa_tstp);
 
 	statusp = 1;
 	child_pid = fork();
@@ -332,6 +339,9 @@
 		PAM_END;
 		exit(1);
 	case 0:
+		sigaction(SIGINT, &sa_int, NULL);
+		sigaction(SIGQUIT, &sa_quit, NULL);
+		sigaction(SIGTSTP, &sa_tstp, NULL);
 		/*
 		 * Set all user context except for: Environmental variables
 		 * Umask Login records (wtmp, etc) Path
@@ -388,7 +398,6 @@
 		if (ruid != 0)
 			syslog(LOG_NOTICE, "%s to %s%s", username, user,
 			    ontty());
-
 		execv(shell, np);
 		err(1, "%s", shell);
 	}

--IJpNTDwzlM2Ie8A6--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-audit" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010613143921.A65820>