mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 00:56:10 +00:00 
			
		
		
		
	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.
This commit is contained in:
		
							
								
								
									
										11
									
								
								client.c
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								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);
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										19
									
								
								server-msg.c
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								tmux.h
									
									
									
									
									
								
							@@ -19,7 +19,7 @@
 | 
			
		||||
#ifndef TMUX_H
 | 
			
		||||
#define TMUX_H
 | 
			
		||||
 | 
			
		||||
#define PROTOCOL_VERSION 1
 | 
			
		||||
#define PROTOCOL_VERSION 2
 | 
			
		||||
 | 
			
		||||
#include <sys/param.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
@@ -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 *);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										46
									
								
								tty.c
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								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);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user