Merge branch 'obsd-master'

This commit is contained in:
Thomas Adam
2026-05-22 16:54:06 +01:00
5 changed files with 93 additions and 27 deletions

View File

@@ -61,6 +61,7 @@ cmd_attach_session(struct cmdq_item *item, const char *tflag, int dflag,
struct window_pane *wp;
char *cwd, *cause;
enum msgtype msgtype;
uid_t uid;
if (RB_EMPTY(&sessions)) {
cmdq_error(item, "no sessions");
@@ -106,8 +107,16 @@ cmd_attach_session(struct cmdq_item *item, const char *tflag, int dflag,
}
if (fflag)
server_client_set_flags(c, fflag);
if (rflag)
if (rflag) {
if (c->flags & CLIENT_READONLY) {
uid = proc_get_peer_uid(c->peer);
if (uid != getuid()) {
cmdq_error(item, "client is read-only");
return (CMD_RETURN_ERROR);
}
}
c->flags |= (CLIENT_READONLY|CLIENT_IGNORESIZE);
}
c->last_session = c->session;
if (c->session != NULL) {

View File

@@ -59,6 +59,7 @@ cmd_detach_client_exec(struct cmd *self, struct cmdq_item *item)
{
struct args *args = cmd_get_args(self);
struct cmd_find_state *source = cmdq_get_source(item);
struct client *c = cmdq_get_client(item);
struct client *tc = cmdq_get_target_client(item), *loop;
struct session *s;
enum msgtype msgtype;
@@ -69,6 +70,13 @@ cmd_detach_client_exec(struct cmd *self, struct cmdq_item *item)
return (CMD_RETURN_NORMAL);
}
if (c->flags & CLIENT_READONLY) {
if (args_has(args, 's') || args_has(args, 'a') || c != tc) {
cmdq_error(item, "client is read-only");
return (CMD_RETURN_ERROR);
}
}
if (args_has(args, 'P'))
msgtype = MSG_DETACHKILL;
else

View File

@@ -20,6 +20,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "tmux.h"
@@ -53,6 +54,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item)
const char *tflag = args_get(args, 't');
enum cmd_find_type type;
int flags;
struct client *c = cmdq_get_client(item);
struct client *tc = cmdq_get_target_client(item);
struct session *s;
struct winlink *wl;
@@ -61,6 +63,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item)
const char *tablename;
struct key_table *table;
struct sort_criteria sort_crit;
uid_t uid;
if (tflag != NULL &&
(tflag[strcspn(tflag, ":.%")] != '\0' || strcmp(tflag, "=") == 0)) {
@@ -77,6 +80,13 @@ cmd_switch_client_exec(struct cmd *self, struct cmdq_item *item)
wp = target.wp;
if (args_has(args, 'r')) {
if (tc->flags & CLIENT_READONLY) {
uid = proc_get_peer_uid(c->peer);
if (uid != getuid()) {
cmdq_error(item, "client is read-only");
return (CMD_RETURN_ERROR);
}
}
if (tc->flags & CLIENT_READONLY)
tc->flags &= ~(CLIENT_READONLY|CLIENT_IGNORESIZE);
else

View File

@@ -172,10 +172,43 @@ screen_write_set_client_cb(struct tty_ctx *ttyctx, struct client *c)
return (1);
}
/* Return 1 if there is a floating window pane overlapping this pane. */
static int
screen_write_pane_is_obscured(struct screen_write_ctx *ctx)
{
struct window_pane *wp = ctx->wp;
if (ctx->wp == NULL)
return (0);
if (ctx->flags & SCREEN_WRITE_CHECKED_IF_OBSCURED) {
if (ctx->flags & SCREEN_WRITE_OBSCURED)
return (1);
return (0);
}
ctx->flags |= SCREEN_WRITE_CHECKED_IF_OBSCURED;
while ((wp = TAILQ_PREV(wp, window_panes, zentry)) != NULL) {
if ((wp->flags & PANE_FLOATING) &&
((wp->yoff >= ctx->wp->yoff &&
wp->yoff <= ctx->wp->yoff + (int)ctx->wp->sy) ||
(wp->yoff + (int)wp->sy >= ctx->wp->yoff &&
wp->yoff + wp->sy <= ctx->wp->yoff + ctx->wp->sy)) &&
((wp->xoff >= ctx->wp->xoff &&
wp->xoff <= ctx->wp->xoff + (int)ctx->wp->sx) ||
(wp->xoff + (int)wp->sx >= ctx->wp->xoff &&
wp->xoff + wp->sx <= ctx->wp->xoff + ctx->wp->sx))) {
ctx->flags |= SCREEN_WRITE_OBSCURED;
return (1);
}
}
return (0);
}
/* Set up context for TTY command. */
static void
screen_write_initctx(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx,
int sync)
int is_sync, int check_obscured)
{
struct screen *s = ctx->s;
@@ -190,6 +223,9 @@ screen_write_initctx(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx,
ttyctx->orlower = s->rlower;
ttyctx->orupper = s->rupper;
if (check_obscured && screen_write_pane_is_obscured(ctx))
ttyctx->flags |= TTY_CTX_PANE_OBSCURED;
memcpy(&ttyctx->defaults, &grid_default_cell, sizeof ttyctx->defaults);
if (ctx->init_ctx_cb != NULL) {
ctx->init_ctx_cb(ctx, ttyctx);
@@ -221,7 +257,7 @@ screen_write_initctx(struct screen_write_ctx *ctx, struct tty_ctx *ttyctx,
else {
if (ctx->wp == NULL)
ttyctx->flags |= TTY_CTX_OVERLAY_SYNC;
if (sync)
if (is_sync)
ttyctx->flags |= TTY_CTX_SYNC;
}
tty_write(tty_cmd_syncstart, ttyctx);
@@ -588,7 +624,7 @@ screen_write_fast_copy(struct screen_write_ctx *ctx, struct screen *src,
break;
s->cx = cx;
if (wp != NULL)
screen_write_initctx(ctx, &ttyctx, 0);
screen_write_initctx(ctx, &ttyctx, 0, 0);
for (xx = px; xx < px + nx; xx++) {
gl = grid_get_line(gd, yy);
sgl = grid_get_line(ctx->s->grid, s->cy);
@@ -1096,7 +1132,7 @@ screen_write_alignmenttest(struct screen_write_ctx *ctx)
s->rupper = 0;
s->rlower = screen_size_y(s) - 1;
screen_write_initctx(ctx, &ttyctx, 1);
screen_write_initctx(ctx, &ttyctx, 1, 1);
screen_write_collect_clear(ctx, 0, screen_size_y(s) - 1);
tty_write(tty_cmd_alignmenttest, &ttyctx);
@@ -1125,7 +1161,7 @@ screen_write_insertcharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg)
ctx->wp->flags |= PANE_REDRAW;
#endif
screen_write_initctx(ctx, &ttyctx, 0);
screen_write_initctx(ctx, &ttyctx, 0, 1);
ttyctx.bg = bg;
grid_view_insert_cells(s->grid, s->cx, s->cy, nx, bg);
@@ -1158,7 +1194,7 @@ screen_write_deletecharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg)
ctx->wp->flags |= PANE_REDRAW;
#endif
screen_write_initctx(ctx, &ttyctx, 0);
screen_write_initctx(ctx, &ttyctx, 0, 1);
ttyctx.bg = bg;
grid_view_delete_cells(s->grid, s->cx, s->cy, nx, bg);
@@ -1191,7 +1227,7 @@ screen_write_clearcharacter(struct screen_write_ctx *ctx, u_int nx, u_int bg)
ctx->wp->flags |= PANE_REDRAW;
#endif
screen_write_initctx(ctx, &ttyctx, 0);
screen_write_initctx(ctx, &ttyctx, 0, 0);
ttyctx.bg = bg;
grid_view_clear(s->grid, s->cx, s->cy, nx, 1, bg);
@@ -1227,7 +1263,7 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
if (ny == 0)
return;
screen_write_initctx(ctx, &ttyctx, 1);
screen_write_initctx(ctx, &ttyctx, 1, 1);
ttyctx.bg = bg;
grid_view_insert_lines(gd, s->cy, ny, bg);
@@ -1243,7 +1279,7 @@ screen_write_insertline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
if (ny == 0)
return;
screen_write_initctx(ctx, &ttyctx, 1);
screen_write_initctx(ctx, &ttyctx, 1, 1);
ttyctx.bg = bg;
if (s->cy < s->rupper || s->cy > s->rlower)
@@ -1280,7 +1316,7 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
if (ny == 0)
return;
screen_write_initctx(ctx, &ttyctx, 1);
screen_write_initctx(ctx, &ttyctx, 1, 1);
ttyctx.bg = bg;
grid_view_delete_lines(gd, s->cy, ny, bg);
@@ -1296,7 +1332,7 @@ screen_write_deleteline(struct screen_write_ctx *ctx, u_int ny, u_int bg)
if (ny == 0)
return;
screen_write_initctx(ctx, &ttyctx, 1);
screen_write_initctx(ctx, &ttyctx, 1, 1);
ttyctx.bg = bg;
if (s->cy < s->rupper || s->cy > s->rlower)
@@ -1439,7 +1475,7 @@ screen_write_reverseindex(struct screen_write_ctx *ctx, u_int bg)
grid_view_scroll_region_down(s->grid, s->rupper, s->rlower, bg);
screen_write_collect_flush(ctx, 0, __func__);
screen_write_initctx(ctx, &ttyctx, 1);
screen_write_initctx(ctx, &ttyctx, 1, 0);
ttyctx.bg = bg;
tty_write(tty_cmd_reverseindex, &ttyctx);
@@ -1550,7 +1586,7 @@ screen_write_scrolldown(struct screen_write_ctx *ctx, u_int lines, u_int bg)
struct tty_ctx ttyctx;
u_int i;
screen_write_initctx(ctx, &ttyctx, 1);
screen_write_initctx(ctx, &ttyctx, 1, 1);
ttyctx.bg = bg;
if (lines == 0)
@@ -1592,7 +1628,7 @@ screen_write_clearendofscreen(struct screen_write_ctx *ctx, u_int bg)
ctx->wp->flags |= PANE_REDRAW;
#endif
screen_write_initctx(ctx, &ttyctx, 1);
screen_write_initctx(ctx, &ttyctx, 1, 1);
ttyctx.bg = bg;
/* Scroll into history if it is enabled and clearing entire screen. */
@@ -1626,7 +1662,7 @@ screen_write_clearstartofscreen(struct screen_write_ctx *ctx, u_int bg)
ctx->wp->flags |= PANE_REDRAW;
#endif
screen_write_initctx(ctx, &ttyctx, 1);
screen_write_initctx(ctx, &ttyctx, 1, 1);
ttyctx.bg = bg;
if (s->cy > 0)
@@ -1654,7 +1690,7 @@ screen_write_clearscreen(struct screen_write_ctx *ctx, u_int bg)
ctx->wp->flags |= PANE_REDRAW;
#endif
screen_write_initctx(ctx, &ttyctx, 1);
screen_write_initctx(ctx, &ttyctx, 1, 1);
ttyctx.bg = bg;
/* Scroll into history if it is enabled. */
@@ -1684,7 +1720,7 @@ screen_write_fullredraw(struct screen_write_ctx *ctx)
screen_write_collect_flush(ctx, 0, __func__);
screen_write_initctx(ctx, &ttyctx, 1);
screen_write_initctx(ctx, &ttyctx, 1, 0);
if (ttyctx.redraw_cb != NULL)
ttyctx.redraw_cb(&ttyctx);
}
@@ -1846,7 +1882,7 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only,
if (ctx->scrolled > s->rlower - s->rupper + 1)
ctx->scrolled = s->rlower - s->rupper + 1;
screen_write_initctx(ctx, &ttyctx, 1);
screen_write_initctx(ctx, &ttyctx, 1, 1);
ttyctx.n = ctx->scrolled;
ttyctx.bg = ctx->bg;
tty_write(tty_cmd_scrollup, &ttyctx);
@@ -1873,12 +1909,12 @@ screen_write_collect_flush(struct screen_write_ctx *ctx, int scroll_only,
}
screen_write_set_cursor(ctx, ci->x, y);
if (ci->type == CLEAR) {
screen_write_initctx(ctx, &ttyctx, 1);
screen_write_initctx(ctx, &ttyctx, 1, 0);
ttyctx.bg = ci->bg;
ttyctx.n = ci->used;
tty_write(tty_cmd_clearcharacter, &ttyctx);
} else {
screen_write_initctx(ctx, &ttyctx, 0);
screen_write_initctx(ctx, &ttyctx, 0, 0);
ttyctx.cell = &ci->gc;
if (ci->wrapped)
ttyctx.flags |= TTY_CTX_WRAPPED;
@@ -2101,7 +2137,7 @@ screen_write_cell(struct screen_write_ctx *ctx, const struct grid_cell *gc)
/* Sanity check cursor position. */
if (s->cx > sx - width || s->cy > sy - 1)
return;
screen_write_initctx(ctx, &ttyctx, 0);
screen_write_initctx(ctx, &ttyctx, 0, 0);
/* Handle overwriting of UTF-8 characters. */
gl = grid_get_line(s->grid, s->grid->hsize + s->cy);
@@ -2298,7 +2334,7 @@ screen_write_combine(struct screen_write_ctx *ctx, const struct grid_cell *gc)
* and what it is going to do now.
*/
screen_write_set_cursor(ctx, cx - n, cy);
screen_write_initctx(ctx, &ttyctx, 0);
screen_write_initctx(ctx, &ttyctx, 0, 0);
ttyctx.cell = &last;
if (force_wide)
ttyctx.flags |= TTY_CTX_CELL_INVALIDATE;
@@ -2387,7 +2423,7 @@ screen_write_setselection(struct screen_write_ctx *ctx, const char *clip,
{
struct tty_ctx ttyctx;
screen_write_initctx(ctx, &ttyctx, 0);
screen_write_initctx(ctx, &ttyctx, 0, 0);
ttyctx.sel.clip = clip;
ttyctx.sel.data = str;
ttyctx.sel.size = len;
@@ -2402,7 +2438,7 @@ screen_write_rawstring(struct screen_write_ctx *ctx, u_char *str, u_int len,
{
struct tty_ctx ttyctx;
screen_write_initctx(ctx, &ttyctx, 0);
screen_write_initctx(ctx, &ttyctx, 0, 0);
if (allow_invisible_panes)
ttyctx.flags |= TTY_CTX_INVISIBLE_PANES;
ttyctx.data.data = str;
@@ -2490,7 +2526,7 @@ screen_write_alternateon(struct screen_write_ctx *ctx, struct grid_cell *gc,
server_redraw_window_borders(wp->window);
}
screen_write_initctx(ctx, &ttyctx, 1);
screen_write_initctx(ctx, &ttyctx, 1, 0);
if (ttyctx.redraw_cb != NULL)
ttyctx.redraw_cb(&ttyctx);
}
@@ -2514,7 +2550,7 @@ screen_write_alternateoff(struct screen_write_ctx *ctx, struct grid_cell *gc,
server_redraw_window_borders(wp->window);
}
screen_write_initctx(ctx, &ttyctx, 1);
screen_write_initctx(ctx, &ttyctx, 1, 0);
if (ttyctx.redraw_cb != NULL)
ttyctx.redraw_cb(&ttyctx);
}

3
tmux.h
View File

@@ -1055,6 +1055,8 @@ struct screen_write_ctx {
int flags;
#define SCREEN_WRITE_SYNC 0x1
#define SCREEN_WRITE_OBSCURED 0x2
#define SCREEN_WRITE_CHECKED_IF_OBSCURED 0x4
screen_write_init_ctx_cb init_ctx_cb;
void *arg;
@@ -1740,6 +1742,7 @@ struct tty_ctx {
#define TTY_CTX_OVERLAY_SYNC 0x10
#define TTY_CTX_CELL_DRAW_LINE 0x20
#define TTY_CTX_CELL_INVALIDATE 0x40
#define TTY_CTX_PANE_OBSCURED 0x80
union {
u_int n;