From d250f6932c793dbacbc0594b120c838d8bf4f0ea Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 8 Feb 2024 13:01:13 +0100 Subject: [PATCH] protocol-native: don't allow recursive security context Place the engine name in pipewire.sec.context and make sure that a client with a pipewire.sec.context property can't make new contexts. --- .../module-protocol-native/security-context.c | 41 +++++++++++++++++-- src/pipewire/extensions/security-context.h | 3 +- src/pipewire/keys.h | 1 + 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/modules/module-protocol-native/security-context.c b/src/modules/module-protocol-native/security-context.c index 709f13721..913670259 100644 --- a/src/modules/module-protocol-native/security-context.c +++ b/src/modules/module-protocol-native/security-context.c @@ -35,9 +35,44 @@ static int security_context_create(void *object, { struct resource_data *d = object; struct impl *impl = d->impl; - pw_protocol_add_fd_server(impl->protocol, impl->context->core, - listen_fd, close_fd, props); - return 0; + struct pw_impl_client *client; + const struct pw_properties *cp; + struct pw_properties *p; + int res = 0; + + if (engine_name == NULL) + goto invalid; + + if ((client = impl->context->current_client) == NULL) + goto not_allowed; + if (client->protocol != impl->protocol) + goto not_allowed; + + /* we can't make a nested security context */ + cp = pw_impl_client_get_properties(client); + if (pw_properties_get(cp, PW_KEY_SEC_CONTEXT) != NULL) + goto not_allowed; + + p = props ? pw_properties_new_dict(props) : pw_properties_new(NULL, NULL); + if (p == NULL) + goto not_allowed; + + pw_properties_set(p, PW_KEY_SEC_CONTEXT, engine_name); + + if (pw_protocol_add_fd_server(impl->protocol, impl->context->core, + listen_fd, close_fd, &p->dict) == NULL) + res = -errno; + + pw_properties_free(p); + + return res; + +invalid: + pw_log_warn("missing engine name"); + return -EINVAL; +not_allowed: + pw_log_warn("can't make security context"); + return -EPERM; } static const struct pw_security_context_methods security_context_methods = { diff --git a/src/pipewire/extensions/security-context.h b/src/pipewire/extensions/security-context.h index 211ec400c..4c594b296 100644 --- a/src/pipewire/extensions/security-context.h +++ b/src/pipewire/extensions/security-context.h @@ -73,7 +73,8 @@ struct pw_security_context_methods { * \param engine_name a unique sandbox engine name. * \param listen_fd the fd to listen on for new connections * \param close_fd the fd used to stop listening - * \param props extra (engine_name specific) properties. + * \param props extra (engine_name specific) properties. These will be + * copied on the client that connects through this context. * * See https://gitlab.freedesktop.org/wayland/wayland-protocols/-/blob/main/staging/security-context/engines.md * For a list of engine_names and the properties to set. diff --git a/src/pipewire/keys.h b/src/pipewire/keys.h index 593ee1848..d6699bdaf 100644 --- a/src/pipewire/keys.h +++ b/src/pipewire/keys.h @@ -39,6 +39,7 @@ extern "C" { #define PW_KEY_SEC_LABEL "pipewire.sec.label" /**< client security label, set by protocol*/ #define PW_KEY_SEC_SOCKET "pipewire.sec.socket" /**< client socket name, set by protocol */ +#define PW_KEY_SEC_CONTEXT "pipewire.sec.context" /**< client secure context, set by protocol */ #define PW_KEY_LIBRARY_NAME_SYSTEM "library.name.system" /**< name of the system library to use */ #define PW_KEY_LIBRARY_NAME_LOOP "library.name.loop" /**< name of the loop library to use */