From 4ec38d18b335de42e7560d59b98ba021e9a029d4 Mon Sep 17 00:00:00 2001 From: Leandro Ribeiro Date: Fri, 24 Jan 2020 01:12:59 -0300 Subject: [PATCH] weston-log: replace weston_log_ctx_compositor_destroy() by weston_log_ctx_destroy() The function weston_log_ctx_compositor_destroy(), which destroys struct weston_log_context, takes weston_compositor as argument. We may have a weston_log_context unlinked from a weston_compositor and currently there is no way to destroy it. Add function weston_log_ctx_destroy(), what makes the destruction of weston_log_context independent of weston_compositor. With this change, one could destroy a weston_compositor and keep the related weston_log_context (since now weston_log_context can be destroyed without the need of a weston_compositor). But if weston_compositor gets destroyed it's also necessary to destroy weston_log_context::global, as the debug protocol depends on the compositor. So a listener has been added to the destroy signal of weston_compositor. Signed-off-by: Leandro Ribeiro --- compositor/main.c | 2 +- doc/sphinx/toc/libweston/log.rst | 2 +- include/libweston/libweston.h | 2 +- libweston/weston-log.c | 48 +++++++++++++++++++++++++++----- 4 files changed, 44 insertions(+), 10 deletions(-) diff --git a/compositor/main.c b/compositor/main.c index a0e54eed..94f8e7d2 100644 --- a/compositor/main.c +++ b/compositor/main.c @@ -3381,8 +3381,8 @@ out: weston_log_scope_destroy(log_scope); log_scope = NULL; - weston_log_ctx_compositor_destroy(wet.compositor); weston_compositor_destroy(wet.compositor); + weston_log_ctx_destroy(log_ctx); weston_log_subscriber_destroy_log(logger); weston_log_subscriber_destroy_flight_rec(flight_rec); diff --git a/doc/sphinx/toc/libweston/log.rst b/doc/sphinx/toc/libweston/log.rst index edc8ef27..d768de0d 100644 --- a/doc/sphinx/toc/libweston/log.rst +++ b/doc/sphinx/toc/libweston/log.rst @@ -21,7 +21,7 @@ take place much earlier without the need of a compositor instance. Instantiation of the :type:`weston_log_context` object takes place using :func:`weston_log_ctx_create()` and clean-up/destroy with -:func:`weston_log_ctx_compositor_destroy()`. +:func:`weston_log_ctx_destroy()` or :func:`weston_log_ctx_compositor_destroy()`. Log scopes ---------- diff --git a/include/libweston/libweston.h b/include/libweston/libweston.h index 84fd1e06..57fa183d 100644 --- a/include/libweston/libweston.h +++ b/include/libweston/libweston.h @@ -2045,7 +2045,7 @@ struct weston_log_context * weston_log_ctx_create(void); void -weston_log_ctx_compositor_destroy(struct weston_compositor *compositor); +weston_log_ctx_destroy(struct weston_log_context *log_ctx); int weston_compositor_enable_content_protection(struct weston_compositor *compositor); diff --git a/libweston/weston-log.c b/libweston/weston-log.c index 4cba0e83..43ca1708 100644 --- a/libweston/weston-log.c +++ b/libweston/weston-log.c @@ -66,6 +66,7 @@ */ struct weston_log_context { struct wl_global *global; + struct wl_listener compositor_destroy_listener; struct wl_list scope_list; /**< weston_log_scope::compositor_link */ struct wl_list pending_subscription_list; /**< weston_log_subscription::source_link */ }; @@ -398,6 +399,22 @@ weston_debug_protocol_advertise_scopes(struct weston_log_context *log_ctx, weston_debug_v1_send_available(res, scope->name, scope->desc); } +/** Disable debug-protocol + * + * @param log_ctx The log context where the debug-protocol is linked + * + * @ingroup internal-log + */ +static void +weston_log_ctx_disable_debug_protocol(struct weston_log_context *log_ctx) +{ + if (!log_ctx->global) + return; + + wl_global_destroy(log_ctx->global); + log_ctx->global = NULL; +} + /** Creates weston_log_context structure * * \return NULL in case of failure, or a weston_log_context object in case of @@ -418,27 +435,29 @@ weston_log_ctx_create(void) wl_list_init(&log_ctx->scope_list); wl_list_init(&log_ctx->pending_subscription_list); + wl_list_init(&log_ctx->compositor_destroy_listener.link); return log_ctx; } /** Destroy weston_log_context structure * - * \param compositor The libweston compositor whose weston-debug to tear down. + * \param log_ctx The log context to destroy. * - * Clears weston_compositor::weston_log_ctx. * @ingroup log * */ WL_EXPORT void -weston_log_ctx_compositor_destroy(struct weston_compositor *compositor) +weston_log_ctx_destroy(struct weston_log_context *log_ctx) { - struct weston_log_context *log_ctx = compositor->weston_log_ctx; struct weston_log_scope *scope; struct weston_log_subscription *pending_sub, *pending_sub_tmp; - if (log_ctx->global) - wl_global_destroy(log_ctx->global); + /* We can't destroy the log context if there's still a compositor + * that depends on it. This is an user error */ + assert(wl_list_empty(&log_ctx->compositor_destroy_listener.link)); + + weston_log_ctx_disable_debug_protocol(log_ctx); wl_list_for_each(scope, &log_ctx->scope_list, compositor_link) fprintf(stderr, "Internal warning: debug scope '%s' has not been destroyed.\n", @@ -456,8 +475,20 @@ weston_log_ctx_compositor_destroy(struct weston_compositor *compositor) /* pending_subscription_list should be empty at this point */ free(log_ctx); +} - compositor->weston_log_ctx = NULL; +static void +compositor_destroy_listener(struct wl_listener *listener, void *data) +{ + struct weston_log_context *log_ctx = + wl_container_of(listener, log_ctx, compositor_destroy_listener); + + /* We have to keep this list initalized as weston_log_ctx_destroy() has + * to check if there's any compositor destroy listener registered */ + wl_list_remove(&log_ctx->compositor_destroy_listener.link); + wl_list_init(&log_ctx->compositor_destroy_listener.link); + + weston_log_ctx_disable_debug_protocol(log_ctx); } /** Enable weston-debug protocol extension @@ -493,6 +524,9 @@ weston_compositor_enable_debug_protocol(struct weston_compositor *compositor) if (!log_ctx->global) return; + log_ctx->compositor_destroy_listener.notify = compositor_destroy_listener; + wl_signal_add(&compositor->destroy_signal, &log_ctx->compositor_destroy_listener); + fprintf(stderr, "WARNING: debug protocol has been enabled. " "This is a potential denial-of-service attack vector and " "information leak.\n");