diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2013-10-10 12:13:57 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2013-10-10 12:13:57 +0000 |
commit | df65d81947e08c6ffecc0f31bae0a40aa618b786 (patch) | |
tree | a09762219f3e687b9bd14f592b3bae8971223fb9 /usr.bin/tmux | |
parent | 71eb50d651f99dfac1f294547feb09fb49be3b77 (diff) |
Similarly for MSG_COMMAND - allow full imsg limit not arbitrary 2048.
Diffstat (limited to 'usr.bin/tmux')
-rw-r--r-- | usr.bin/tmux/client.c | 66 | ||||
-rw-r--r-- | usr.bin/tmux/server-client.c | 47 | ||||
-rw-r--r-- | usr.bin/tmux/server-fn.c | 3 | ||||
-rw-r--r-- | usr.bin/tmux/tmux.h | 23 |
4 files changed, 89 insertions, 50 deletions
diff --git a/usr.bin/tmux/client.c b/usr.bin/tmux/client.c index c028837b7ff..8d97b37c271 100644 --- a/usr.bin/tmux/client.c +++ b/usr.bin/tmux/client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: client.c,v 1.69 2013/10/10 12:13:29 nicm Exp $ */ +/* $OpenBSD: client.c,v 1.70 2013/10/10 12:13:56 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -54,7 +54,8 @@ int client_get_lock(char *); int client_connect(char *, int); void client_send_identify(int); void client_send_environ(void); -void client_write_server(enum msgtype, void *, size_t); +int client_write_one(enum msgtype, int, const void *, size_t); +int client_write_server(enum msgtype, const void *, size_t); void client_update_event(void); void client_signal(int, short, void *); void client_stdin_callback(int, short, void *); @@ -165,12 +166,13 @@ client_main(int argc, char **argv, int flags) { struct cmd *cmd; struct cmd_list *cmdlist; - struct msg_command_data cmddata; - int cmdflags, fd; + struct msg_command_data *data; + int cmdflags, fd, i; pid_t ppid; enum msgtype msg; char *cause; struct termios tio, saved_tio; + size_t size; /* Set up the initial command. */ cmdflags = 0; @@ -261,19 +263,32 @@ client_main(int argc, char **argv, int flags) /* Send first command. */ if (msg == MSG_COMMAND) { + /* How big is the command? */ + size = 0; + for (i = 0; i < argc; i++) + size += strlen(argv[i]) + 1; + data = xmalloc((sizeof *data) + size); + /* Fill in command line arguments. */ - cmddata.pid = environ_pid; - cmddata.session_id = environ_session_id; + data->pid = environ_pid; + data->session_id = environ_session_id; /* Prepare command for server. */ - cmddata.argc = argc; - if (cmd_pack_argv( - argc, argv, cmddata.argv, sizeof cmddata.argv) != 0) { + data->argc = argc; + if (cmd_pack_argv(argc, argv, (char*)(data + 1), size) != 0) { fprintf(stderr, "command too long\n"); + free(data); return (1); } + size += sizeof *data; - client_write_server(msg, &cmddata, sizeof cmddata); + /* Send the command. */ + if (client_write_server(msg, data, size) != 0) { + fprintf(stderr, "failed to send command\n"); + free(data); + return (1); + } + free(data); } else if (msg == MSG_SHELL) client_write_server(msg, NULL, 0); @@ -340,12 +355,29 @@ client_send_environ(void) } } +/* Helper to send one message. */ +int +client_write_one(enum msgtype type, int fd, const void *buf, size_t len) +{ + int retval; + + retval = imsg_compose(&client_ibuf, type, PROTOCOL_VERSION, -1, fd, + (void*)buf, len); + if (retval != 1) + return (-1); + return (0); +} + /* Write a message to the server without a file descriptor. */ -void -client_write_server(enum msgtype type, void *buf, size_t len) +int +client_write_server(enum msgtype type, const void *buf, size_t len) { - imsg_compose(&client_ibuf, type, PROTOCOL_VERSION, -1, -1, buf, len); - client_update_event(); + int retval; + + retval = client_write_one(type, -1, buf, len); + if (retval == 0) + client_update_event(); + return (retval); } /* Update client event based on whether it needs to read or read and write. */ @@ -528,14 +560,16 @@ client_dispatch_wait(void *data0) fatalx("bad MSG_STDOUT size"); memcpy(&stdoutdata, data, sizeof stdoutdata); - client_write(STDOUT_FILENO, stdoutdata.data, stdoutdata.size); + client_write(STDOUT_FILENO, stdoutdata.data, + stdoutdata.size); break; case MSG_STDERR: if (datalen != sizeof stderrdata) fatalx("bad MSG_STDERR size"); memcpy(&stderrdata, data, sizeof stderrdata); - client_write(STDERR_FILENO, stderrdata.data, stderrdata.size); + client_write(STDERR_FILENO, stderrdata.data, + stderrdata.size); break; case MSG_VERSION: if (datalen != 0) diff --git a/usr.bin/tmux/server-client.c b/usr.bin/tmux/server-client.c index 2f4fee778da..f13df492cbe 100644 --- a/usr.bin/tmux/server-client.c +++ b/usr.bin/tmux/server-client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server-client.c,v 1.107 2013/10/10 12:13:29 nicm Exp $ */ +/* $OpenBSD: server-client.c,v 1.108 2013/10/10 12:13:56 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> @@ -40,7 +40,7 @@ void server_client_reset_state(struct client *); int server_client_assume_paste(struct session *); int server_client_msg_dispatch(struct client *); -void server_client_msg_command(struct client *, struct msg_command_data *); +void server_client_msg_command(struct client *, struct imsg *); void server_client_msg_identify( struct client *, struct msg_identify_data *, int); void server_client_msg_shell(struct client *); @@ -786,10 +786,10 @@ int server_client_msg_dispatch(struct client *c) { struct imsg imsg; - struct msg_command_data commanddata; struct msg_identify_data identifydata; struct msg_environ_data environdata; struct msg_stdin_data stdindata; + const char *data; ssize_t n, datalen; if ((n = imsg_read(&c->ibuf)) == -1 || n == 0) @@ -800,6 +800,8 @@ server_client_msg_dispatch(struct client *c) return (-1); if (n == 0) return (0); + + data = imsg.data; datalen = imsg.hdr.len - IMSG_HEADER_SIZE; if (imsg.hdr.peerid != PROTOCOL_VERSION) { @@ -811,13 +813,6 @@ server_client_msg_dispatch(struct client *c) log_debug("got %d from client %d", imsg.hdr.type, c->ibuf.fd); switch (imsg.hdr.type) { - case MSG_COMMAND: - if (datalen != sizeof commanddata) - fatalx("bad MSG_COMMAND size"); - memcpy(&commanddata, imsg.data, sizeof commanddata); - - server_client_msg_command(c, &commanddata); - break; case MSG_IDENTIFY: if (datalen != sizeof identifydata) fatalx("bad MSG_IDENTIFY size"); @@ -825,10 +820,13 @@ server_client_msg_dispatch(struct client *c) server_client_msg_identify(c, &identifydata, imsg.fd); break; + case MSG_COMMAND: + server_client_msg_command(c, &imsg); + break; case MSG_STDIN: if (datalen != sizeof stdindata) fatalx("bad MSG_STDIN size"); - memcpy(&stdindata, imsg.data, sizeof stdindata); + memcpy(&stdindata, data, sizeof stdindata); if (c->stdin_callback == NULL) break; @@ -903,15 +901,26 @@ server_client_msg_dispatch(struct client *c) /* Handle command message. */ void -server_client_msg_command(struct client *c, struct msg_command_data *data) +server_client_msg_command(struct client *c, struct imsg *imsg) { - struct cmd_list *cmdlist = NULL; - int argc; - char **argv, *cause; - - argc = data->argc; - data->argv[(sizeof data->argv) - 1] = '\0'; - if (cmd_unpack_argv(data->argv, sizeof data->argv, argc, &argv) != 0) { + struct msg_command_data data; + char *buf; + size_t len; + struct cmd_list *cmdlist = NULL; + int argc; + char **argv, *cause; + + if (imsg->hdr.len - IMSG_HEADER_SIZE < sizeof data) + fatalx("bad MSG_COMMAND size"); + memcpy(&data, imsg->data, sizeof data); + + buf = (char*)imsg->data + sizeof data; + len = imsg->hdr.len - IMSG_HEADER_SIZE - sizeof data; + if (len > 0 && buf[len - 1] != '\0') + fatalx("bad MSG_COMMAND string"); + + argc = data.argc; + if (cmd_unpack_argv(buf, len, argc, &argv) != 0) { cmdq_error(c->cmdq, "command too long"); goto error; } diff --git a/usr.bin/tmux/server-fn.c b/usr.bin/tmux/server-fn.c index 1f7bb859611..0e3363fbba4 100644 --- a/usr.bin/tmux/server-fn.c +++ b/usr.bin/tmux/server-fn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server-fn.c,v 1.72 2013/10/10 12:13:29 nicm Exp $ */ +/* $OpenBSD: server-fn.c,v 1.73 2013/10/10 12:13:56 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -236,7 +236,6 @@ void server_lock_client(struct client *c) { const char *cmd; - size_t cmdlen; if (c->flags & CLIENT_CONTROL) return; diff --git a/usr.bin/tmux/tmux.h b/usr.bin/tmux/tmux.h index f4a541f570f..2f4f662f95d 100644 --- a/usr.bin/tmux/tmux.h +++ b/usr.bin/tmux/tmux.h @@ -1,4 +1,4 @@ -/* $OpenBSD: tmux.h,v 1.426 2013/10/10 12:13:29 nicm Exp $ */ +/* $OpenBSD: tmux.h,v 1.427 2013/10/10 12:13:56 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -62,7 +62,6 @@ extern char **environ; * Maximum sizes of strings in message data. Don't forget to bump * PROTOCOL_VERSION if any of these change! */ -#define COMMAND_LENGTH 2048 /* packed argv size */ #define TERMINAL_LENGTH 128 /* length of TERM environment variable */ #define ENVIRON_LENGTH 1024 /* environment variable length */ @@ -475,16 +474,14 @@ enum msgtype { * Don't forget to bump PROTOCOL_VERSION if any of these change! */ struct msg_command_data { - pid_t pid; /* from $TMUX or -1 */ - int session_id; /* from $TMUX or -1 */ + pid_t pid; /* from $TMUX or -1 */ + int session_id; /* from $TMUX or -1 */ - int argc; - char argv[COMMAND_LENGTH]; -}; + int argc; +}; /* followed by packed argv */ struct msg_identify_data { char cwd[MAXPATHLEN]; - char term[TERMINAL_LENGTH]; int flags; @@ -1319,7 +1316,7 @@ struct client { #define CLIENT_EXIT 0x4 #define CLIENT_REDRAW 0x8 #define CLIENT_STATUS 0x10 -#define CLIENT_REPEAT 0x20 /* allow command to repeat within repeat time */ +#define CLIENT_REPEAT 0x20 #define CLIENT_SUSPENDED 0x40 #define CLIENT_BAD 0x80 #define CLIENT_IDENTIFY 0x100 @@ -1922,10 +1919,10 @@ void server_window_loop(void); /* server-fn.c */ void server_fill_environ(struct session *, struct environ *); void server_write_ready(struct client *); -int server_write_client( - struct client *, enum msgtype, const void *, size_t); -void server_write_session( - struct session *, enum msgtype, const void *, size_t); +int server_write_client(struct client *, enum msgtype, const void *, + size_t); +void server_write_session(struct session *, enum msgtype, const void *, + size_t); void server_redraw_client(struct client *); void server_status_client(struct client *); void server_redraw_session(struct session *); |