mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-04 23:50:27 +00:00
Put child process in a different process group, ensure that the broadcast
signal never affects su directly, some shells changes its pgrp at running or suspended time, so a broadcast SIGTSTP from child will mess up su's job control. Discussed with: bde
This commit is contained in:
parent
5bbb806004
commit
a75fd4bf6e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=112695
|
@ -130,7 +130,8 @@ main(int argc, char *argv[])
|
||||||
statusp, child_pid, child_pgrp, ret_pid, setmaclabel;
|
statusp, child_pid, child_pgrp, ret_pid, setmaclabel;
|
||||||
char *username, *cleanenv, *class, shellbuf[MAXPATHLEN];
|
char *username, *cleanenv, *class, shellbuf[MAXPATHLEN];
|
||||||
const char *p, *user, *shell, *mytty, **nargv;
|
const char *p, *user, *shell, *mytty, **nargv;
|
||||||
struct sigaction sa, sa_int, sa_quit;
|
struct sigaction sa, sa_int, sa_quit, sa_pipe;
|
||||||
|
int temp, fds[2];
|
||||||
|
|
||||||
shell = class = cleanenv = NULL;
|
shell = class = cleanenv = NULL;
|
||||||
asme = asthem = fastlogin = statusp = 0;
|
asme = asthem = fastlogin = statusp = 0;
|
||||||
|
@ -326,20 +327,30 @@ main(int argc, char *argv[])
|
||||||
sigemptyset(&sa.sa_mask);
|
sigemptyset(&sa.sa_mask);
|
||||||
sigaction(SIGINT, &sa, &sa_int);
|
sigaction(SIGINT, &sa, &sa_int);
|
||||||
sigaction(SIGQUIT, &sa, &sa_quit);
|
sigaction(SIGQUIT, &sa, &sa_quit);
|
||||||
|
sigaction(SIGPIPE, &sa, &sa_pipe);
|
||||||
sa.sa_handler = SIG_DFL;
|
sa.sa_handler = SIG_DFL;
|
||||||
sigaction(SIGTSTP, &sa, NULL);
|
sigaction(SIGTSTP, &sa, NULL);
|
||||||
statusp = 1;
|
statusp = 1;
|
||||||
|
if (pipe(fds) == -1) {
|
||||||
|
err(1, "pipe");
|
||||||
|
PAM_END();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
child_pid = fork();
|
child_pid = fork();
|
||||||
switch (child_pid) {
|
switch (child_pid) {
|
||||||
default:
|
default:
|
||||||
while ((ret_pid = waitpid(child_pid, &statusp, WUNTRACED)) != -1) {
|
close(fds[0]);
|
||||||
|
setpgid(child_pid, child_pid);
|
||||||
|
tcsetpgrp(1, child_pid);
|
||||||
|
close(fds[1]);
|
||||||
|
sigaction(SIGPIPE, &sa_pipe, NULL);
|
||||||
|
while ((ret_pid = waitpid(child_pid, &statusp, WUNTRACED)) !=
|
||||||
|
-1) {
|
||||||
if (WIFSTOPPED(statusp)) {
|
if (WIFSTOPPED(statusp)) {
|
||||||
kill(getpid(), SIGSTOP);
|
kill(getpid(), SIGSTOP);
|
||||||
child_pgrp = getpgid(child_pid);
|
child_pgrp = getpgid(child_pid);
|
||||||
if (tcgetpgrp(1) == getpgrp()) {
|
|
||||||
tcsetpgrp(1, child_pgrp);
|
tcsetpgrp(1, child_pgrp);
|
||||||
kill(child_pid, SIGCONT);
|
kill(child_pid, SIGCONT);
|
||||||
}
|
|
||||||
statusp = 1;
|
statusp = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -354,8 +365,13 @@ main(int argc, char *argv[])
|
||||||
PAM_END();
|
PAM_END();
|
||||||
exit(1);
|
exit(1);
|
||||||
case 0:
|
case 0:
|
||||||
|
close(fds[1]);
|
||||||
|
read(fds[0], &temp, 1);
|
||||||
|
close(fds[0]);
|
||||||
|
sigaction(SIGPIPE, &sa_pipe, NULL);
|
||||||
sigaction(SIGINT, &sa_int, NULL);
|
sigaction(SIGINT, &sa_int, NULL);
|
||||||
sigaction(SIGQUIT, &sa_quit, NULL);
|
sigaction(SIGQUIT, &sa_quit, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set all user context except for: Environmental variables
|
* Set all user context except for: Environmental variables
|
||||||
* Umask Login records (wtmp, etc) Path
|
* Umask Login records (wtmp, etc) Path
|
||||||
|
|
Loading…
Reference in a new issue