From 46e4ea43a2ec546211f72be84b6a55188fb61626 Mon Sep 17 00:00:00 2001 From: Derek Foreman Date: Wed, 6 Dec 2017 11:22:20 -0600 Subject: [PATCH] connection: Make wl_closure_destroy() close fds of undispatched closures When we have a closure that can't be dispatched for some reason, and it contains file descriptors, we must close those descriptors to prevent leaking them. Previous commits ensure that only FDs belonging to this invocation of the closure, i.e. not FDs provided by the client for marshalling, nor FDs which have already been dispatched to either client or server, will be left in the closure by destroy time. Signed-off-by: Derek Foreman Reviewed-by: Daniel Stone --- src/connection.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/connection.c b/src/connection.c index 29f565bb..e92de794 100644 --- a/src/connection.c +++ b/src/connection.c @@ -1273,8 +1273,29 @@ wl_closure_print(struct wl_closure *closure, struct wl_object *target, int send) fprintf(stderr, ")\n"); } +static int +wl_closure_close_fds(struct wl_closure *closure) +{ + int i; + struct argument_details arg; + const char *signature = closure->message->signature; + + for (i = 0; i < closure->count; i++) { + signature = get_next_argument(signature, &arg); + if (arg.type == 'h' && closure->args[i].h != -1) + close(closure->args[i].h); + } + + return 0; +} + void wl_closure_destroy(struct wl_closure *closure) { + /* wl_closure_destroy has free() semantics */ + if (!closure) + return; + + wl_closure_close_fds(closure); free(closure); }