A few additional readonly checks, GitHub issue 5736 from gmkbenjamin at

hotmail dot com.
This commit is contained in:
nicm
2026-10-15 07:25:07 +00:00
committed by tmux update bot
parent cf8c6ec235
commit 610bf01351
5 changed files with 49 additions and 11 deletions

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: cmd-attach-session.c,v 1.93 2026/10/09 13:12:14 nicm Exp $ */ /* $OpenBSD: cmd-attach-session.c,v 1.94 2026/10/15 07:25:07 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -55,7 +55,7 @@ cmd_attach_session(struct cmdq_item *item, const char *tflag, int dflag,
struct cmd_find_state *current = cmdq_get_current(item); struct cmd_find_state *current = cmdq_get_current(item);
struct cmd_find_state target; struct cmd_find_state target;
enum cmd_find_type type; enum cmd_find_type type;
int flags; int flags, ro = 0;
struct client *c = cmdq_get_client(item), *c_loop; struct client *c = cmdq_get_client(item), *c_loop;
struct session *s; struct session *s;
struct winlink *wl; struct winlink *wl;
@@ -72,6 +72,14 @@ cmd_attach_session(struct cmdq_item *item, const char *tflag, int dflag,
if (c == NULL) if (c == NULL)
return (CMD_RETURN_NORMAL); return (CMD_RETURN_NORMAL);
if (c->flags & CLIENT_READONLY) {
if (dflag || xflag || cflag != NULL) {
cmdq_error(item, "client is read-only");
return (CMD_RETURN_ERROR);
}
ro = 1;
}
if (server_client_check_nested(c)) { if (server_client_check_nested(c)) {
cmdq_error(item, "sessions should be nested with care, " cmdq_error(item, "sessions should be nested with care, "
"unset $TMUX to force"); "unset $TMUX to force");
@@ -91,6 +99,11 @@ cmd_attach_session(struct cmdq_item *item, const char *tflag, int dflag,
wl = target.wl; wl = target.wl;
wp = target.wp; wp = target.wp;
if (ro && (wl != s->curw || (wp != NULL && wp != wp->window->active))) {
cmdq_error(item, "client is read-only");
return (CMD_RETURN_ERROR);
}
if (wl != NULL) { if (wl != NULL) {
if (wp != NULL) { if (wp != NULL) {
window_redraw_active_switch(wp->window, wp); window_redraw_active_switch(wp->window, wp);
@@ -111,7 +124,7 @@ cmd_attach_session(struct cmdq_item *item, const char *tflag, int dflag,
if (fflag) if (fflag)
server_client_set_flags(c, fflag); server_client_set_flags(c, fflag);
if (rflag) { if (rflag) {
if (c->flags & CLIENT_READONLY) { if (ro) {
uid = proc_get_peer_uid(c->peer); uid = proc_get_peer_uid(c->peer);
if (uid != getuid()) { if (uid != getuid()) {
cmdq_error(item, "client is read-only"); cmdq_error(item, "client is read-only");
@@ -134,7 +147,7 @@ cmd_attach_session(struct cmdq_item *item, const char *tflag, int dflag,
server_client_detach(c_loop, msgtype); server_client_detach(c_loop, msgtype);
} }
} }
if (!Eflag) if (!Eflag && (~c->flags & CLIENT_READONLY))
environ_update(s->options, c->environ, s->environ); environ_update(s->options, c->environ, s->environ);
server_client_set_session(c, s); server_client_set_session(c, s);
@@ -158,7 +171,7 @@ cmd_attach_session(struct cmdq_item *item, const char *tflag, int dflag,
server_client_detach(c_loop, msgtype); server_client_detach(c_loop, msgtype);
} }
} }
if (!Eflag) if (!Eflag && (~c->flags & CLIENT_READONLY))
environ_update(s->options, c->environ, s->environ); environ_update(s->options, c->environ, s->environ);
server_client_set_session(c, s); server_client_set_session(c, s);

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: cmd-queue.c,v 1.124 2026/09/22 06:46:50 nicm Exp $ */ /* $OpenBSD: cmd-queue.c,v 1.125 2026/10/15 07:25:07 nicm Exp $ */
/* /*
* Copyright (c) 2013 Nicholas Marriott <nicholas.marriott@gmail.com> * Copyright (c) 2013 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -595,6 +595,15 @@ cmdq_fire_command(struct cmdq_item *item)
flags = !!(state->flags & CMDQ_STATE_CONTROL); flags = !!(state->flags & CMDQ_STATE_CONTROL);
cmdq_guard(item, "begin", flags); cmdq_guard(item, "begin", flags);
if (flags &&
saved != NULL &&
(saved->flags & CLIENT_READONLY) &&
(~entry->flags & CMD_READONLY)) {
cmdq_error(item, "client is read-only");
retval = CMD_RETURN_ERROR;
goto out;
}
if (item->client == NULL) if (item->client == NULL)
item->client = cmd_find_client(item, NULL, 1); item->client = cmd_find_client(item, NULL, 1);

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: cmd-send-keys.c,v 1.82 2026/10/09 13:12:14 nicm Exp $ */ /* $OpenBSD: cmd-send-keys.c,v 1.83 2026/10/15 07:25:07 nicm Exp $ */
/* /*
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com> * Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -164,6 +164,7 @@ cmd_send_keys_exec(struct cmd *self, struct cmdq_item *item)
{ {
struct args *args = cmd_get_args(self); struct args *args = cmd_get_args(self);
struct cmd_find_state *target = cmdq_get_target(item); struct cmd_find_state *target = cmdq_get_target(item);
struct client *c = cmdq_get_client(item);
struct client *tc = cmdq_get_target_client(item); struct client *tc = cmdq_get_target_client(item);
struct session *s = target->s; struct session *s = target->s;
struct winlink *wl = target->wl; struct winlink *wl = target->wl;
@@ -177,7 +178,8 @@ cmd_send_keys_exec(struct cmd *self, struct cmdq_item *item)
u_int count = args_count(args); u_int count = args_count(args);
char *cause = NULL; char *cause = NULL;
if (tc != NULL && tc->flags & CLIENT_READONLY && !args_has(args, 'X')) { if ((c != NULL && (c->flags & CLIENT_READONLY) && c != tc) ||
(tc != NULL && (tc->flags & CLIENT_READONLY) && !args_has(args, 'X'))) {
cmdq_error(item, "client is read-only"); cmdq_error(item, "client is read-only");
return (CMD_RETURN_ERROR); return (CMD_RETURN_ERROR);
} }

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: cmd-switch-client.c,v 1.76 2026/10/09 13:12:14 nicm Exp $ */ /* $OpenBSD: cmd-switch-client.c,v 1.77 2026/10/15 07:25:07 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com> * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -66,6 +66,11 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item)
struct sort_criteria sort_crit; struct sort_criteria sort_crit;
uid_t uid; uid_t uid;
if (c != NULL && (c->flags & CLIENT_READONLY) && c != tc) {
cmdq_error(item, "client is read-only");
return (CMD_RETURN_ERROR);
}
if (tflag != NULL && if (tflag != NULL &&
(tflag[strcspn(tflag, ":.%")] != '\0' || strcmp(tflag, "=") == 0)) { (tflag[strcspn(tflag, ":.%")] != '\0' || strcmp(tflag, "=") == 0)) {
type = CMD_FIND_PANE; type = CMD_FIND_PANE;
@@ -80,6 +85,12 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item)
wl = target.wl; wl = target.wl;
wp = target.wp; wp = target.wp;
if (c != NULL && (c->flags & CLIENT_READONLY) &&
(wl != s->curw || (wp != NULL && wp != wp->window->active))) {
cmdq_error(item, "client is read-only");
return (CMD_RETURN_ERROR);
}
if (args_has(args, 'r')) { if (args_has(args, 'r')) {
if (tc->flags & CLIENT_READONLY) { if (tc->flags & CLIENT_READONLY) {
uid = proc_get_peer_uid(c->peer); uid = proc_get_peer_uid(c->peer);
@@ -157,7 +168,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item)
} }
} }
if (!args_has(args, 'E')) if (!args_has(args, 'E') && (~tc->flags & CLIENT_READONLY))
environ_update(s->options, tc->environ, s->environ); environ_update(s->options, tc->environ, s->environ);
server_client_set_session(tc, s); server_client_set_session(tc, s);

View File

@@ -1,4 +1,4 @@
/* $OpenBSD: format.c,v 1.428 2026/10/13 10:21:58 nicm Exp $ */ /* $OpenBSD: format.c,v 1.429 2026/10/15 07:25:07 nicm Exp $ */
/* /*
* Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com> * Copyright (c) 2011 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -4271,7 +4271,10 @@ format_create_add_item(struct format_tree *ft, struct cmdq_item *item)
{ {
struct key_event *event = cmdq_get_event(item); struct key_event *event = cmdq_get_event(item);
struct mouse_event *m = &event->m; struct mouse_event *m = &event->m;
struct client *c = cmdq_get_client(item);
if (c != NULL && (c->flags & CLIENT_READONLY))
ft->flags |= FORMAT_NOJOBS;
cmdq_merge_formats(item, ft); cmdq_merge_formats(item, ft);
memcpy(&ft->m, m, sizeof ft->m); memcpy(&ft->m, m, sizeof ft->m);
} }