mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-04-22 05:25:03 -05:00
When allocating BSD-style ptys, we should not be satisfied with a
/dev/ptyXX we can open: we must also check that we can open and use the corresponding /dev/ttyXX, because if it's been left in the wrong mode then we will look terribly silly when we fork and _then_ discover our pty is unusable. [originally from svn r5257]
This commit is contained in:
parent
0eb1e5df8d
commit
fd961b398a
38
unix/uxpty.c
38
unix/uxpty.c
@ -70,7 +70,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static Config pty_cfg;
|
static Config pty_cfg;
|
||||||
static int pty_master_fd;
|
static int pty_master_fd, pty_slave_fd;
|
||||||
static void *pty_frontend;
|
static void *pty_frontend;
|
||||||
static char pty_name[FILENAME_MAX];
|
static char pty_name[FILENAME_MAX];
|
||||||
static int pty_signal_pipe[2];
|
static int pty_signal_pipe[2];
|
||||||
@ -186,6 +186,14 @@ static void fatal_sig_handler(int signum)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int pty_open_slave(void)
|
||||||
|
{
|
||||||
|
if (pty_slave_fd < 0)
|
||||||
|
pty_slave_fd = open(pty_name, O_RDWR);
|
||||||
|
|
||||||
|
return pty_slave_fd;
|
||||||
|
}
|
||||||
|
|
||||||
static void pty_open_master(void)
|
static void pty_open_master(void)
|
||||||
{
|
{
|
||||||
#ifdef BSD_PTYS
|
#ifdef BSD_PTYS
|
||||||
@ -201,8 +209,24 @@ static void pty_open_master(void)
|
|||||||
pty_master_fd = open(master_name, O_RDWR);
|
pty_master_fd = open(master_name, O_RDWR);
|
||||||
if (pty_master_fd >= 0) {
|
if (pty_master_fd >= 0) {
|
||||||
if (geteuid() == 0 ||
|
if (geteuid() == 0 ||
|
||||||
access(master_name, R_OK | W_OK) == 0)
|
access(master_name, R_OK | W_OK) == 0) {
|
||||||
goto got_one;
|
/*
|
||||||
|
* We must also check at this point that we are
|
||||||
|
* able to open the slave side of the pty. We
|
||||||
|
* wouldn't want to allocate the wrong master,
|
||||||
|
* get all the way down to forking, and _then_
|
||||||
|
* find we're unable to open the slave.
|
||||||
|
*/
|
||||||
|
strcpy(pty_name, master_name);
|
||||||
|
pty_name[5] = 't'; /* /dev/ptyXX -> /dev/ttyXX */
|
||||||
|
|
||||||
|
if (pty_open_slave() >= 0 &&
|
||||||
|
access(pty_name, R_OK | W_OK) == 0)
|
||||||
|
goto got_one;
|
||||||
|
if (pty_slave_fd > 0)
|
||||||
|
close(pty_slave_fd);
|
||||||
|
pty_slave_fd = -1;
|
||||||
|
}
|
||||||
close(pty_master_fd);
|
close(pty_master_fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -212,8 +236,6 @@ static void pty_open_master(void)
|
|||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
got_one:
|
got_one:
|
||||||
strcpy(pty_name, master_name);
|
|
||||||
pty_name[5] = 't'; /* /dev/ptyXX -> /dev/ttyXX */
|
|
||||||
|
|
||||||
/* We need to chown/chmod the /dev/ttyXX device. */
|
/* We need to chown/chmod the /dev/ttyXX device. */
|
||||||
gp = getgrnam("tty");
|
gp = getgrnam("tty");
|
||||||
@ -265,7 +287,7 @@ void pty_pre_init(void)
|
|||||||
/* set the child signal handler straight away; it needs to be set
|
/* set the child signal handler straight away; it needs to be set
|
||||||
* before we ever fork. */
|
* before we ever fork. */
|
||||||
putty_signal(SIGCHLD, sigchld_handler);
|
putty_signal(SIGCHLD, sigchld_handler);
|
||||||
pty_master_fd = -1;
|
pty_master_fd = pty_slave_fd = -1;
|
||||||
|
|
||||||
if (geteuid() != getuid() || getegid() != getgid()) {
|
if (geteuid() != getuid() || getegid() != getgid()) {
|
||||||
pty_open_master();
|
pty_open_master();
|
||||||
@ -564,7 +586,7 @@ static const char *pty_init(void *frontend, void **backend_handle, Config *cfg,
|
|||||||
* We are the child.
|
* We are the child.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
slavefd = open(pty_name, O_RDWR);
|
slavefd = pty_open_slave();
|
||||||
if (slavefd < 0) {
|
if (slavefd < 0) {
|
||||||
perror("slave pty: open");
|
perror("slave pty: open");
|
||||||
_exit(1);
|
_exit(1);
|
||||||
@ -652,6 +674,8 @@ static const char *pty_init(void *frontend, void **backend_handle, Config *cfg,
|
|||||||
pty_child_pid = pid;
|
pty_child_pid = pid;
|
||||||
pty_child_dead = FALSE;
|
pty_child_dead = FALSE;
|
||||||
pty_finished = FALSE;
|
pty_finished = FALSE;
|
||||||
|
if (pty_slave_fd > 0)
|
||||||
|
close(pty_slave_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pipe(pty_signal_pipe) < 0) {
|
if (pipe(pty_signal_pipe) < 0) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user