mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-03-22 14:39:24 -05:00
We shouldn't fork off a utmp helper subprocess when we aren't setuid,
because (a) under that circumstance we won't be writing to utmp anyway, and (b) if we aren't setuid, then we won't have created the pty at the point we fork, so even if our subprocess _could_ have written to utmp it wouldn't have done it right! Spotted by valgrind (triggering on the access beyond the end of the ttyname string in setup_utmp, clueing me in to it having been empty). [originally from svn r9309]
This commit is contained in:
parent
73444adc50
commit
f69591412c
158
unix/uxpty.c
158
unix/uxpty.c
@ -167,8 +167,8 @@ static tree234 *ptys_by_pid = NULL;
|
|||||||
static Pty single_pty = NULL;
|
static Pty single_pty = NULL;
|
||||||
|
|
||||||
#ifndef OMIT_UTMP
|
#ifndef OMIT_UTMP
|
||||||
static pid_t pty_utmp_helper_pid;
|
static pid_t pty_utmp_helper_pid = -1;
|
||||||
static int pty_utmp_helper_pipe;
|
static int pty_utmp_helper_pipe = -1;
|
||||||
static int pty_stamped_utmp;
|
static int pty_stamped_utmp;
|
||||||
static struct utmpx utmp_entry;
|
static struct utmpx utmp_entry;
|
||||||
#endif
|
#endif
|
||||||
@ -408,106 +408,106 @@ void pty_pre_init(void)
|
|||||||
|
|
||||||
if (geteuid() != getuid() || getegid() != getgid()) {
|
if (geteuid() != getuid() || getegid() != getgid()) {
|
||||||
pty_open_master(pty);
|
pty_open_master(pty);
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef OMIT_UTMP
|
#ifndef OMIT_UTMP
|
||||||
/*
|
/*
|
||||||
* Fork off the utmp helper.
|
* Fork off the utmp helper.
|
||||||
*/
|
*/
|
||||||
if (pipe(pipefd) < 0) {
|
if (pipe(pipefd) < 0) {
|
||||||
perror("pterm: pipe");
|
perror("pterm: pipe");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
cloexec(pipefd[0]);
|
cloexec(pipefd[0]);
|
||||||
cloexec(pipefd[1]);
|
cloexec(pipefd[1]);
|
||||||
pid = fork();
|
pid = fork();
|
||||||
if (pid < 0) {
|
if (pid < 0) {
|
||||||
perror("pterm: fork");
|
perror("pterm: fork");
|
||||||
exit(1);
|
exit(1);
|
||||||
} else if (pid == 0) {
|
} else if (pid == 0) {
|
||||||
char display[128], buffer[128];
|
char display[128], buffer[128];
|
||||||
int dlen, ret;
|
int dlen, ret;
|
||||||
|
|
||||||
close(pipefd[1]);
|
close(pipefd[1]);
|
||||||
/*
|
/*
|
||||||
* Now sit here until we receive a display name from the
|
* Now sit here until we receive a display name from the
|
||||||
* other end of the pipe, and then stamp utmp. Unstamp utmp
|
* other end of the pipe, and then stamp utmp. Unstamp utmp
|
||||||
* again, and exit, when the pipe closes.
|
* again, and exit, when the pipe closes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
dlen = 0;
|
dlen = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
||||||
ret = read(pipefd[0], buffer, lenof(buffer));
|
ret = read(pipefd[0], buffer, lenof(buffer));
|
||||||
if (ret <= 0) {
|
if (ret <= 0) {
|
||||||
cleanup_utmp();
|
cleanup_utmp();
|
||||||
_exit(0);
|
_exit(0);
|
||||||
} else if (!pty_stamped_utmp) {
|
} else if (!pty_stamped_utmp) {
|
||||||
if (dlen < lenof(display))
|
if (dlen < lenof(display))
|
||||||
memcpy(display+dlen, buffer,
|
memcpy(display+dlen, buffer,
|
||||||
min(ret, lenof(display)-dlen));
|
min(ret, lenof(display)-dlen));
|
||||||
if (buffer[ret-1] == '\0') {
|
if (buffer[ret-1] == '\0') {
|
||||||
/*
|
/*
|
||||||
* Now we have a display name. NUL-terminate
|
* Now we have a display name. NUL-terminate
|
||||||
* it, and stamp utmp.
|
* it, and stamp utmp.
|
||||||
*/
|
*/
|
||||||
display[lenof(display)-1] = '\0';
|
display[lenof(display)-1] = '\0';
|
||||||
/*
|
/*
|
||||||
* Trap as many fatal signals as we can in the
|
* Trap as many fatal signals as we can in the
|
||||||
* hope of having the best possible chance to
|
* hope of having the best possible chance to
|
||||||
* clean up utmp before termination. We are
|
* clean up utmp before termination. We are
|
||||||
* unfortunately unprotected against SIGKILL,
|
* unfortunately unprotected against SIGKILL,
|
||||||
* but that's life.
|
* but that's life.
|
||||||
*/
|
*/
|
||||||
putty_signal(SIGHUP, fatal_sig_handler);
|
putty_signal(SIGHUP, fatal_sig_handler);
|
||||||
putty_signal(SIGINT, fatal_sig_handler);
|
putty_signal(SIGINT, fatal_sig_handler);
|
||||||
putty_signal(SIGQUIT, fatal_sig_handler);
|
putty_signal(SIGQUIT, fatal_sig_handler);
|
||||||
putty_signal(SIGILL, fatal_sig_handler);
|
putty_signal(SIGILL, fatal_sig_handler);
|
||||||
putty_signal(SIGABRT, fatal_sig_handler);
|
putty_signal(SIGABRT, fatal_sig_handler);
|
||||||
putty_signal(SIGFPE, fatal_sig_handler);
|
putty_signal(SIGFPE, fatal_sig_handler);
|
||||||
putty_signal(SIGPIPE, fatal_sig_handler);
|
putty_signal(SIGPIPE, fatal_sig_handler);
|
||||||
putty_signal(SIGALRM, fatal_sig_handler);
|
putty_signal(SIGALRM, fatal_sig_handler);
|
||||||
putty_signal(SIGTERM, fatal_sig_handler);
|
putty_signal(SIGTERM, fatal_sig_handler);
|
||||||
putty_signal(SIGSEGV, fatal_sig_handler);
|
putty_signal(SIGSEGV, fatal_sig_handler);
|
||||||
putty_signal(SIGUSR1, fatal_sig_handler);
|
putty_signal(SIGUSR1, fatal_sig_handler);
|
||||||
putty_signal(SIGUSR2, fatal_sig_handler);
|
putty_signal(SIGUSR2, fatal_sig_handler);
|
||||||
#ifdef SIGBUS
|
#ifdef SIGBUS
|
||||||
putty_signal(SIGBUS, fatal_sig_handler);
|
putty_signal(SIGBUS, fatal_sig_handler);
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGPOLL
|
#ifdef SIGPOLL
|
||||||
putty_signal(SIGPOLL, fatal_sig_handler);
|
putty_signal(SIGPOLL, fatal_sig_handler);
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGPROF
|
#ifdef SIGPROF
|
||||||
putty_signal(SIGPROF, fatal_sig_handler);
|
putty_signal(SIGPROF, fatal_sig_handler);
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGSYS
|
#ifdef SIGSYS
|
||||||
putty_signal(SIGSYS, fatal_sig_handler);
|
putty_signal(SIGSYS, fatal_sig_handler);
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGTRAP
|
#ifdef SIGTRAP
|
||||||
putty_signal(SIGTRAP, fatal_sig_handler);
|
putty_signal(SIGTRAP, fatal_sig_handler);
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGVTALRM
|
#ifdef SIGVTALRM
|
||||||
putty_signal(SIGVTALRM, fatal_sig_handler);
|
putty_signal(SIGVTALRM, fatal_sig_handler);
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGXCPU
|
#ifdef SIGXCPU
|
||||||
putty_signal(SIGXCPU, fatal_sig_handler);
|
putty_signal(SIGXCPU, fatal_sig_handler);
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGXFSZ
|
#ifdef SIGXFSZ
|
||||||
putty_signal(SIGXFSZ, fatal_sig_handler);
|
putty_signal(SIGXFSZ, fatal_sig_handler);
|
||||||
#endif
|
#endif
|
||||||
#ifdef SIGIO
|
#ifdef SIGIO
|
||||||
putty_signal(SIGIO, fatal_sig_handler);
|
putty_signal(SIGIO, fatal_sig_handler);
|
||||||
|
#endif
|
||||||
|
setup_utmp(pty->name, display);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
close(pipefd[0]);
|
||||||
|
pty_utmp_helper_pid = pid;
|
||||||
|
pty_utmp_helper_pipe = pipefd[1];
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
setup_utmp(pty->name, display);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
close(pipefd[0]);
|
|
||||||
pty_utmp_helper_pid = pid;
|
|
||||||
pty_utmp_helper_pipe = pipefd[1];
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Drop privs. */
|
/* Drop privs. */
|
||||||
{
|
{
|
||||||
@ -735,7 +735,7 @@ static const char *pty_init(void *frontend, void **backend_handle, Conf *conf,
|
|||||||
if (!conf_get_int(conf, CONF_stamp_utmp)) {
|
if (!conf_get_int(conf, CONF_stamp_utmp)) {
|
||||||
close(pty_utmp_helper_pipe); /* just let the child process die */
|
close(pty_utmp_helper_pipe); /* just let the child process die */
|
||||||
pty_utmp_helper_pipe = -1;
|
pty_utmp_helper_pipe = -1;
|
||||||
} else {
|
} else if (pty_utmp_helper_pipe >= 0) {
|
||||||
char *location = get_x_display(pty->frontend);
|
char *location = get_x_display(pty->frontend);
|
||||||
int len = strlen(location)+1, pos = 0; /* +1 to include NUL */
|
int len = strlen(location)+1, pos = 0; /* +1 to include NUL */
|
||||||
while (pos < len) {
|
while (pos < len) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user