From 91c662fa59f49e5cb547ca83e5741a8bece3aaf9 Mon Sep 17 00:00:00 2001 From: llyyr Date: Thu, 23 Apr 2026 00:40:25 +0530 Subject: [PATCH 1/5] sway/server: chase wlroots!5327 Ref: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/5327 --- sway/server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sway/server.c b/sway/server.c index 8bdafb674..c481c7e99 100644 --- a/sway/server.c +++ b/sway/server.c @@ -227,7 +227,7 @@ static void handle_renderer_lost(struct wl_listener *listener, void *data) { } static void handle_new_foreign_toplevel_capture_request(struct wl_listener *listener, void *data) { - struct wlr_ext_foreign_toplevel_image_capture_source_manager_v1_request *request = data; + struct wlr_ext_foreign_toplevel_image_capture_source_manager_v1_request_event *request = data; struct sway_view *view = request->toplevel_handle->data; if (view->image_capture_source == NULL) { @@ -561,7 +561,7 @@ bool server_init(struct sway_server *server) { return false; } server->new_foreign_toplevel_capture_request.notify = handle_new_foreign_toplevel_capture_request; - wl_signal_add(&server->ext_foreign_toplevel_image_capture_source_manager_v1->events.new_request, + wl_signal_add(&server->ext_foreign_toplevel_image_capture_source_manager_v1->events.capture_request, &server->new_foreign_toplevel_capture_request); server->tearing_control_v1 = From 80a940a99254fe5cc2ffce20c0e52aacb60ec7f6 Mon Sep 17 00:00:00 2001 From: Hugo Osvaldo Barrera Date: Thu, 23 Apr 2026 14:09:02 +0200 Subject: [PATCH 2/5] Treat ext-workspace-v1 as privileged And do not expose it to clients in security contexts. Fixes: https://github.com/swaywm/sway/issues/9120 --- sway/server.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sway/server.c b/sway/server.c index c481c7e99..92d4fe5ed 100644 --- a/sway/server.c +++ b/sway/server.c @@ -126,7 +126,8 @@ static bool is_privileged(const struct wl_global *global) { global == server.input->virtual_keyboard->global || global == server.input->virtual_pointer->global || global == server.input->transient_seat_manager->global || - global == server.xdg_output_manager_v1->global; + global == server.xdg_output_manager_v1->global || + global == server.workspace_manager_v1->global; } static bool filter_global(const struct wl_client *client, From 1cbb8a440f157047292709c171e59f0feeb26475 Mon Sep 17 00:00:00 2001 From: Hugo Osvaldo Barrera Date: Thu, 23 Apr 2026 15:30:18 +0200 Subject: [PATCH 3/5] Ignore failures creating linux-drm-syncobj Failures creating this global are non-fatal. Fixes: 1606311553cb58a280e320907098bd0f443fef6e Fixes: https://github.com/swaywm/sway/issues/9110 --- sway/server.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sway/server.c b/sway/server.c index 92d4fe5ed..8c55c0395 100644 --- a/sway/server.c +++ b/sway/server.c @@ -296,11 +296,8 @@ bool server_init(struct sway_server *server) { if (wlr_renderer_get_drm_fd(server->renderer) >= 0 && server->renderer->features.timeline && server->backend->features.timeline) { - if (!wlr_linux_drm_syncobj_manager_v1_create(server->wl_display, 1, - wlr_renderer_get_drm_fd(server->renderer))) { - sway_log(SWAY_ERROR, "Failed to create linux-drm-syncobj v1"); - return false; - } + wlr_linux_drm_syncobj_manager_v1_create(server->wl_display, 1, + wlr_renderer_get_drm_fd(server->renderer)); } server->allocator = wlr_allocator_autocreate(server->backend, From 1084d2e87abc8f608270042df7c88f76302d8d9e Mon Sep 17 00:00:00 2001 From: llyyr Date: Wed, 1 Apr 2026 01:24:28 +0530 Subject: [PATCH 4/5] sway/desktop/transaction: skip freeing dirty nodes This fixes a race that causes UAF when turning on multiple outputs after they've been off for a while. When output_begin_destroy is called while a transaction that references the output is in-flight, node_set_dirty adds the node to server.dirty_nodes list and ntxnrefs is still held by that transaction. Once the transaction completes and ntxnrefs drops to 0, transaction_destroy frees the output, leaving a dangling pointer in server.dirty_nodes. The next transaction_commit_dirty call then walks the dirty_nodes list and crashes The fix is to skip the free in transaction_destroy if node->dirty is set, this means transaction_commit_dirty hasn't processed this node yet and will bump ntxnrefs shortly. The free will happen once that transaction completes and ntxnrefs reaches 0 again and transaction_commit_dirty will allocate a fresh instruction and increment ntxnrefs again when it processes the node. --- sway/desktop/transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c index d4e853dee..082fe20ce 100644 --- a/sway/desktop/transaction.c +++ b/sway/desktop/transaction.c @@ -59,7 +59,7 @@ static void transaction_destroy(struct sway_transaction *transaction) { if (node->instruction == instruction) { node->instruction = NULL; } - if (node->destroying && node->ntxnrefs == 0) { + if (node->destroying && node->ntxnrefs == 0 && !node->dirty) { switch (node->type) { case N_ROOT: sway_assert(false, "Never reached"); From c857ca3a978896f4f9bdd481ec5cf395662a2dc5 Mon Sep 17 00:00:00 2001 From: Furkan Sahin Date: Sun, 1 Feb 2026 21:53:06 -0500 Subject: [PATCH 5/5] tree/workspace: fix crash on dragging container to workspace edge When a container is moved, `finalize_move` previously assumed that calling `workspace_split` would always result in a workspace with exactly 1 child (the wrapper container). Consequently, it safely assumed that inserting a container with `after = 1` was always valid. However, if the moved container was the only child of its workspace, calling `container_detach` drops the workspace's tiling length to 0. Calling `workspace_split` on an empty workspace simply changes its layout enum and returns, leaving the length at 0. Passing `after` (which evaluates to 1 when moving right/down) into `workspace_insert_tiling` then causes an out-of-bounds insertion and a subsequent segmentation fault during `container_build_representation`. This commit fixes the issue by dynamically calculating the insertion index based on the actual length of the workspace's tiling list at the moment of insertion, rather than overloading the `after` boolean flag as a hardcoded index. --- sway/input/seatop_move_tiling.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sway/input/seatop_move_tiling.c b/sway/input/seatop_move_tiling.c index c525b77a9..f19c3f18b 100644 --- a/sway/input/seatop_move_tiling.c +++ b/sway/input/seatop_move_tiling.c @@ -373,7 +373,7 @@ static void finalize_move(struct sway_seat *seat) { enum sway_container_layout new_layout = edge == WLR_EDGE_TOP || edge == WLR_EDGE_BOTTOM ? L_VERT : L_HORIZ; workspace_split(new_ws, new_layout); - workspace_insert_tiling(new_ws, con, after); + workspace_insert_tiling(new_ws, con, after ? new_ws->tiling->length : 0); } if (old_parent) {