mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
Apply the correct fix for bin/50679: don't mess around with process groups
or the tty, just block selected signals in the parent like system(3) does. Many thanks to bde for his assistance in finding the correct solution. PR: bin/50679
This commit is contained in:
parent
7e9b53e399
commit
e947f78c16
1 changed files with 19 additions and 13 deletions
|
|
@ -287,54 +287,60 @@ pw_mkdb(const char *user)
|
|||
int
|
||||
pw_edit(int notsetuid)
|
||||
{
|
||||
struct sigaction sa, sa_int, sa_quit;
|
||||
sigset_t sigset, oldsigset;
|
||||
struct stat st1, st2;
|
||||
const char *editor;
|
||||
char *editcmd;
|
||||
int pstat;
|
||||
|
||||
if ((editor = getenv("EDITOR")) == NULL)
|
||||
editor = _PATH_VI;
|
||||
if (stat(tempname, &st1) == -1)
|
||||
return (-1);
|
||||
sa.sa_handler = SIG_IGN;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
sigaction(SIGINT, &sa, &sa_int);
|
||||
sigaction(SIGQUIT, &sa, &sa_quit);
|
||||
sigemptyset(&sigset);
|
||||
sigaddset(&sigset, SIGCHLD);
|
||||
sigprocmask(SIG_BLOCK, &sigset, &oldsigset);
|
||||
switch ((editpid = fork())) {
|
||||
case -1:
|
||||
return (-1);
|
||||
case 0:
|
||||
/* child */
|
||||
sigaction(SIGINT, &sa_int, NULL);
|
||||
sigaction(SIGQUIT, &sa_quit, NULL);
|
||||
sigprocmask(SIG_SETMASK, &oldsigset, NULL);
|
||||
if (notsetuid) {
|
||||
(void)setgid(getgid());
|
||||
(void)setuid(getuid());
|
||||
}
|
||||
if (asprintf(&editcmd, "exec %s %s", editor, tempname) == NULL)
|
||||
_exit(EXIT_FAILURE);
|
||||
errno = 0;
|
||||
execl(_PATH_BSHELL, "sh", "-c", editcmd, NULL);
|
||||
free(editcmd);
|
||||
execlp(editor, editor, tempname, NULL);
|
||||
_exit(errno);
|
||||
default:
|
||||
/* parent */
|
||||
break;
|
||||
}
|
||||
setpgid(editpid, editpid);
|
||||
tcsetpgrp(1, editpid);
|
||||
for (;;) {
|
||||
if (waitpid(editpid, &pstat, WUNTRACED) == -1) {
|
||||
unlink(tempname);
|
||||
return (-1);
|
||||
break;
|
||||
} else if (WIFSTOPPED(pstat)) {
|
||||
raise(WSTOPSIG(pstat));
|
||||
tcsetpgrp(1, getpgid(editpid));
|
||||
kill(editpid, SIGCONT);
|
||||
} else if (WIFEXITED(pstat) && WEXITSTATUS(pstat) == 0) {
|
||||
editpid = -1;
|
||||
break;
|
||||
} else {
|
||||
unlink(tempname);
|
||||
*tempname = '\0';
|
||||
editpid = -1;
|
||||
return (-1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
sigaction(SIGINT, &sa_int, NULL);
|
||||
sigaction(SIGQUIT, &sa_quit, NULL);
|
||||
sigprocmask(SIG_SETMASK, &oldsigset, NULL);
|
||||
if (stat(tempname, &st2) == -1)
|
||||
return (-1);
|
||||
return (st1.st_mtime != st2.st_mtime);
|
||||
|
|
|
|||
Loading…
Reference in a new issue