summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Marriott <nicm@cvs.openbsd.org>2015-10-17 18:30:44 +0000
committerNicholas Marriott <nicm@cvs.openbsd.org>2015-10-17 18:30:44 +0000
commit49628163b2edd8dc83096406209d7988fc051839 (patch)
tree3ea430d1ab8f2243bee1e9629bcb4774b8a2de58
parent35ad62ac41848a1f73b58753760b8f57b8024a3a (diff)
Add pledge "stdio unix sendfd proc exec tty" to tmux client process,
"sendfd" is dropped after first message from the server.
-rw-r--r--usr.bin/tmux/client.c55
1 files changed, 41 insertions, 14 deletions
diff --git a/usr.bin/tmux/client.c b/usr.bin/tmux/client.c
index 3c19ef2977b..dca2cedbb16 100644
--- a/usr.bin/tmux/client.c
+++ b/usr.bin/tmux/client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: client.c,v 1.96 2015/10/11 00:26:23 guenther Exp $ */
+/* $OpenBSD: client.c,v 1.97 2015/10/17 18:30:43 nicm Exp $ */
/*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@@ -55,7 +55,7 @@ int client_attached;
__dead void client_exec(const char *);
int client_get_lock(char *);
int client_connect(struct event_base *, char *, int);
-void client_send_identify(void);
+void client_send_identify(const char *, int);
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);
@@ -214,7 +214,8 @@ client_main(struct event_base *base, int argc, char **argv, int flags)
struct cmd *cmd;
struct cmd_list *cmdlist;
struct msg_command_data *data;
- int cmdflags, fd, i;
+ int cmdflags, fd, i, cwd;
+ const char* ttynam;
pid_t ppid;
enum msgtype msg;
char *cause;
@@ -272,6 +273,26 @@ client_main(struct event_base *base, int argc, char **argv, int flags)
}
return (1);
}
+
+ /* Save these before pledge(). */
+ if ((cwd = open(".", O_RDONLY)) == -1)
+ cwd = open("/", O_RDONLY);
+ if ((ttynam = ttyname(STDIN_FILENO)) == NULL)
+ ttynam = "";
+
+ /*
+ * Drop privileges for client. "proc exec" is needed for -c and for
+ * locking (which uses system(3)).
+ *
+ * "tty" is needed to restore termios(4) and also for some reason -CC
+ * does not work properly without it (input is not recognised).
+ *
+ * "sendfd" is dropped later in client_dispatch_wait().
+ */
+ if (pledge("stdio unix sendfd proc exec tty", NULL) != 0)
+ fatal("pledge failed");
+
+ /* Free stuff that is not used in the client. */
options_free(&global_options);
options_free(&global_s_options);
options_free(&global_w_options);
@@ -304,7 +325,7 @@ client_main(struct event_base *base, int argc, char **argv, int flags)
}
/* Send identify messages. */
- client_send_identify();
+ client_send_identify(ttynam, cwd); /* closes cwd */
/* Send first command. */
if (msg == MSG_COMMAND) {
@@ -359,7 +380,7 @@ client_main(struct event_base *base, int argc, char **argv, int flags)
/* Send identify messages to server. */
void
-client_send_identify(void)
+client_send_identify(const char *ttynam, int cwd)
{
const char *s;
char **ss;
@@ -373,13 +394,8 @@ client_send_identify(void)
s = "";
client_write_one(MSG_IDENTIFY_TERM, -1, s, strlen(s) + 1);
- if ((s = ttyname(STDIN_FILENO)) == NULL)
- s = "";
- client_write_one(MSG_IDENTIFY_TTYNAME, -1, s, strlen(s) + 1);
-
- if ((fd = open(".", O_RDONLY)) == -1)
- fd = open("/", O_RDONLY);
- client_write_one(MSG_IDENTIFY_CWD, fd, NULL, 0);
+ client_write_one(MSG_IDENTIFY_TTYNAME, -1, ttynam, strlen(ttynam) + 1);
+ client_write_one(MSG_IDENTIFY_CWD, cwd, NULL, 0);
if ((fd = dup(STDIN_FILENO)) == -1)
fatal("dup failed");
@@ -395,8 +411,6 @@ client_send_identify(void)
}
client_write_one(MSG_IDENTIFY_DONE, -1, NULL, 0);
-
- client_update_event();
}
/* Helper to send one message. */
@@ -587,6 +601,19 @@ client_dispatch_wait(void)
struct msg_stdout_data stdoutdata;
struct msg_stderr_data stderrdata;
int retval;
+ static int pledge_applied;
+
+ /*
+ * "sendfd" is no longer required once all of the identify messages
+ * have been sent. We know the server won't send us anything until that
+ * point (because we don't ask it to), so we can drop "sendfd" once we
+ * get the first message from the server.
+ */
+ if (!pledge_applied) {
+ if (pledge("stdio unix proc exec tty", NULL) != 0)
+ fatal("pledge failed");
+ pledge_applied = 1;
+ };
for (;;) {
if ((n = imsg_get(&client_ibuf, &imsg)) == -1)