We need to close file descriptors sent to zombie proxies to avoid leaking them, and perhaps more importantly, to prevent them from being dispatched in events on other objects (since they would previously be left in the buffer and potentially fed to following events destined for live proxies)
Reviewed-by: Daniel Stone <dani...@collabora.com> Signed-off-by: Derek Foreman <der...@osg.samsung.com> --- src/connection.c | 6 ++++++ src/wayland-client.c | 18 ++++++++++++++++-- src/wayland-private.h | 3 +++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/connection.c b/src/connection.c index 04e2c7f..206b35d 100644 --- a/src/connection.c +++ b/src/connection.c @@ -192,6 +192,12 @@ close_fds(struct wl_buffer *buffer, int max) buffer->tail += size; } +void +wl_connection_close_fds_in(struct wl_connection *connection, int max) +{ + close_fds(&connection->fds_in, max); +} + int wl_connection_destroy(struct wl_connection *connection) { diff --git a/src/wayland-client.c b/src/wayland-client.c index 0ee36b8..4c1264f 100644 --- a/src/wayland-client.c +++ b/src/wayland-client.c @@ -1304,12 +1304,14 @@ increase_closure_args_refcount(struct wl_closure *closure) static int queue_event(struct wl_display *display, int len) { + void *map_entry; uint32_t p[2], id; int opcode, size; struct wl_proxy *proxy; struct wl_closure *closure; const struct wl_message *message; struct wl_event_queue *queue; + bool is_zombie; wl_connection_copy(display->connection, p, sizeof p); id = p[0]; @@ -1318,12 +1320,24 @@ queue_event(struct wl_display *display, int len) if (len < size) return 0; - proxy = wl_map_lookup(&display->objects, id); - if (!proxy || wl_object_is_zombie(&display->objects, id)) { + map_entry = wl_map_lookup(&display->objects, id); + is_zombie = wl_object_is_zombie(&display->objects, id); + if (!map_entry && !is_zombie) { wl_connection_consume(display->connection, size); return size; } + if (is_zombie) { + struct wl_zombie *zombie = map_entry; + + if (zombie) + wl_connection_close_fds_in(display->connection, + zombie->fd_count[opcode]); + + wl_connection_consume(display->connection, size); + return size; + } + proxy = map_entry; message = &proxy->object.interface->events[opcode]; closure = wl_connection_demarshal(display->connection, size, &display->objects, message); diff --git a/src/wayland-private.h b/src/wayland-private.h index 8e94864..12b9032 100644 --- a/src/wayland-private.h +++ b/src/wayland-private.h @@ -253,4 +253,7 @@ wl_priv_signal_get(struct wl_priv_signal *signal, wl_notify_func_t notify); void wl_priv_signal_emit(struct wl_priv_signal *signal, void *data); +void +wl_connection_close_fds_in(struct wl_connection *connection, int max); + #endif -- 2.15.0 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/wayland-devel