From 64caf59e84c3ae1c06773bb8ec91165eeedabe6d Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Wed, 23 Sep 2009 06:05:02 +0000 Subject: [PATCH] Don't attempt to open() the tty path, rely on the client sending its stdin fd with imsg and fatal if it doesn't, then set the FD_CLOEXEC flag in tty_init instead of tty_open to prevent them leaking into child processes if any are created between the two calls. This bumps the protocol version, so the tmux server should be killed before upgrading. --- client.c | 11 +++-------- server-msg.c | 19 ++++++++++--------- tmux.h | 6 ++---- tty.c | 46 ++++++++++++++++++++++++---------------------- 4 files changed, 39 insertions(+), 43 deletions(-) diff --git a/client.c b/client.c index 05d5b606..ee3bba50 100644 --- a/client.c +++ b/client.c @@ -45,7 +45,7 @@ client_init(char *path, struct client_ctx *cctx, int cmdflags, int flags) struct winsize ws; size_t size; int fd, fd2, mode; - char *name, *term; + char *term; char rpathbuf[MAXPATHLEN]; if (realpath(path, rpathbuf) == NULL) @@ -113,13 +113,8 @@ server_started: *data.term = '\0'; } - *data.tty = '\0'; - if ((name = ttyname(STDIN_FILENO)) == NULL) - fatal("ttyname failed"); - if (strlcpy(data.tty, name, sizeof data.tty) >= sizeof data.tty) - fatalx("ttyname failed"); - - fd2 = dup(STDIN_FILENO); + if ((fd2 = dup(STDIN_FILENO)) == -1) + fatal("dup failed"); imsg_compose(&cctx->ibuf, MSG_IDENTIFY, PROTOCOL_VERSION, -1, fd2, &data, sizeof data); } diff --git a/server-msg.c b/server-msg.c index cb5dbf06..cf0f346c 100644 --- a/server-msg.c +++ b/server-msg.c @@ -74,6 +74,8 @@ server_msg_dispatch(struct client *c) case MSG_IDENTIFY: if (datalen != sizeof identifydata) fatalx("bad MSG_IDENTIFY size"); + if (imsg.fd == -1) + fatalx("MSG_IDENTIFY missing fd"); memcpy(&identifydata, imsg.data, sizeof identifydata); server_msg_identify(c, &identifydata, imsg.fd); @@ -243,21 +245,13 @@ error: void server_msg_identify(struct client *c, struct msg_identify_data *data, int fd) { - c->tty.sx = data->sx; - if (c->tty.sx == 0) - c->tty.sx = 80; - c->tty.sy = data->sy; - if (c->tty.sy == 0) - c->tty.sy = 24; - c->cwd = NULL; data->cwd[(sizeof data->cwd) - 1] = '\0'; if (*data->cwd != '\0') c->cwd = xstrdup(data->cwd); - data->tty[(sizeof data->tty) - 1] = '\0'; data->term[(sizeof data->term) - 1] = '\0'; - tty_init(&c->tty, fd, data->tty, data->term); + tty_init(&c->tty, fd, data->term); if (data->flags & IDENTIFY_UTF8) c->tty.flags |= TTY_UTF8; if (data->flags & IDENTIFY_256COLOURS) @@ -267,6 +261,13 @@ server_msg_identify(struct client *c, struct msg_identify_data *data, int fd) if (data->flags & IDENTIFY_HASDEFAULTS) c->tty.term_flags |= TERM_HASDEFAULTS; + c->tty.sx = data->sx; + if (c->tty.sx == 0) + c->tty.sx = 80; + c->tty.sy = data->sy; + if (c->tty.sy == 0) + c->tty.sy = 24; + c->flags |= CLIENT_TERMINAL; } diff --git a/tmux.h b/tmux.h index 0ffb0b53..bdaf5f6e 100644 --- a/tmux.h +++ b/tmux.h @@ -19,7 +19,7 @@ #ifndef TMUX_H #define TMUX_H -#define PROTOCOL_VERSION 1 +#define PROTOCOL_VERSION 2 #include #include @@ -328,8 +328,6 @@ struct msg_command_data { }; struct msg_identify_data { - char tty[TTY_NAME_MAX]; - char cwd[MAXPATHLEN]; char term[TERMINAL_LENGTH]; @@ -1200,7 +1198,7 @@ void tty_putcode2(struct tty *, enum tty_code_code, int, int); void tty_puts(struct tty *, const char *); void tty_putc(struct tty *, u_char); void tty_pututf8(struct tty *, const struct grid_utf8 *); -void tty_init(struct tty *, int, char *, char *); +void tty_init(struct tty *, int, char *); void tty_start_tty(struct tty *); void tty_stop_tty(struct tty *); void tty_detect_utf8(struct tty *); diff --git a/tty.c b/tty.c index b0810219..574e9a7b 100644 --- a/tty.c +++ b/tty.c @@ -44,16 +44,31 @@ void tty_cell(struct tty *, const struct grid_cell *, const struct grid_utf8 *); void -tty_init(struct tty *tty, int fd, char *path, char *term) +tty_init(struct tty *tty, int fd, char *term) { - tty->path = xstrdup(path); - tty->fd = fd; + int mode; + char *path; + + memset(tty, 0, sizeof *tty); tty->log_fd = -1; if (term == NULL || *term == '\0') tty->termname = xstrdup("unknown"); else tty->termname = xstrdup(term); + + if ((mode = fcntl(fd, F_GETFL)) == -1) + fatal("fcntl failed"); + if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1) + fatal("fcntl failed"); + if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) + fatal("fcntl failed"); + tty->fd = fd; + + if ((path = ttyname(fd)) == NULL) + fatalx("ttyname failed"); + tty->path = xstrdup(path); + tty->flags = 0; tty->term_flags = 0; } @@ -61,28 +76,15 @@ tty_init(struct tty *tty, int fd, char *path, char *term) int tty_open(struct tty *tty, const char *overrides, char **cause) { - int mode; + int fd; - if (tty->fd == -1) { - tty->fd = open(tty->path, O_RDWR|O_NONBLOCK); - if (tty->fd == -1) { - xasprintf(cause, "%s: %s", tty->path, strerror(errno)); - return (-1); - } + if (debug_level > 3) { + fd = open("tmux.out", O_WRONLY|O_CREAT|O_TRUNC, 0644); + if (fd != -1 && fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) + fatal("fcntl failed"); + tty->log_fd = fd; } - if ((mode = fcntl(tty->fd, F_GETFL)) == -1) - fatal("fcntl failed"); - if (fcntl(tty->fd, F_SETFL, mode|O_NONBLOCK) == -1) - fatal("fcntl failed"); - if (fcntl(tty->fd, F_SETFD, FD_CLOEXEC) == -1) - fatal("fcntl failed"); - - if (debug_level > 3) - tty->log_fd = open("tmux.out", O_WRONLY|O_CREAT|O_TRUNC, 0644); - else - tty->log_fd = -1; - tty->term = tty_term_find(tty->termname, tty->fd, overrides, cause); if (tty->term == NULL) { tty_close(tty);