]> git.mdlowis.com Git - proto/labwc.git/commitdiff
layers: don't send configure events in unmap handler
authortokyo4j <hrak1529@gmail.com>
Fri, 27 Jun 2025 06:10:06 +0000 (15:10 +0900)
committerJohan Malm <johanmalm@users.noreply.github.com>
Fri, 27 Jun 2025 21:03:37 +0000 (22:03 +0100)
Alternative to 7bf08af which was reverted in the previous commit.

7bf08af fixed the problem that layer-shell clients are terminated when
it's unmapped, by sending configure events in node-destroy handler
rather than in unmap handler. But it caused a UAF bug when an output
with layer-shell clients is destroyed.

So this patch fixes the original issue by simply skipping the surface in
arrange_one_layer() if it's being unmapped.

include/layers.h
src/layers.c

index a47d916e20f21f5e0d35b98a9c9ca4af12fb481d..b995fc8b713b6688b171d5ecb3d492a8043b5c21 100644 (file)
@@ -14,6 +14,8 @@ struct lab_layer_surface {
        struct server *server;
 
        bool mapped;
+       /* true only inside handle_unmap() */
+       bool being_unmapped;
 
        struct wl_listener map;
        struct wl_listener unmap;
index d4e6f60d81fde1e222b43b889030c729feff220b..d7d9624d8e116d1f0c64485697227473e63d9db0 100644 (file)
@@ -50,6 +50,9 @@ arrange_one_layer(const struct wlr_box *full_area, struct wlr_box *usable_area,
                if (!scene->layer_surface->initialized) {
                        continue;
                }
+               if (surface->being_unmapped) {
+                       continue;
+               }
                if (!!scene->layer_surface->current.exclusive_zone != exclusive) {
                        continue;
                }
@@ -343,6 +346,18 @@ handle_unmap(struct wl_listener *listener, void *data)
        struct lab_layer_surface *layer = wl_container_of(listener, layer, unmap);
        struct wlr_layer_surface_v1 *layer_surface =
                layer->scene_layer_surface->layer_surface;
+
+       /*
+        * If we send a configure event in unmap handler, the layer-shell
+        * client sends ack_configure back and wlroots posts a
+        * "wrong configure serial" error, which terminates the client (see
+        * https://github.com/labwc/labwc/pull/1154#issuecomment-2906885183).
+        *
+        * To prevent this, we set being_unmapped here and check it in
+        * arrange_one_layer() called by output_update_usable_area().
+        */
+       layer->being_unmapped = true;
+
        if (layer_surface->output) {
                output_update_usable_area(layer_surface->output->data);
        }
@@ -350,6 +365,8 @@ handle_unmap(struct wl_listener *listener, void *data)
        if (seat->focused_layer == layer_surface) {
                try_to_focus_next_layer_or_toplevel(layer->server);
        }
+
+       layer->being_unmapped = false;
 }
 
 static void