X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=meta-pipewire%2Fdynamic-layers%2Fmeta-app-framework%2Frecipes-multimedia%2Fpipewire%2Fpipewire%2F0001-modules-add-new-access-seclabel-module.patch;fp=meta-pipewire%2Fdynamic-layers%2Fmeta-app-framework%2Frecipes-multimedia%2Fpipewire%2Fpipewire%2F0001-modules-add-new-access-seclabel-module.patch;h=7885dfa37e4151bc8f4e43c1b32d74e7be42e999;hb=fc722f8aea13246ce7779acbb3a59681b64131a6;hp=0000000000000000000000000000000000000000;hpb=b81c6beb388cafa6de9ca1baa13c3d529ca2f2d8;p=AGL%2Fmeta-agl.git diff --git a/meta-pipewire/dynamic-layers/meta-app-framework/recipes-multimedia/pipewire/pipewire/0001-modules-add-new-access-seclabel-module.patch b/meta-pipewire/dynamic-layers/meta-app-framework/recipes-multimedia/pipewire/pipewire/0001-modules-add-new-access-seclabel-module.patch new file mode 100644 index 000000000..7885dfa37 --- /dev/null +++ b/meta-pipewire/dynamic-layers/meta-app-framework/recipes-multimedia/pipewire/pipewire/0001-modules-add-new-access-seclabel-module.patch @@ -0,0 +1,265 @@ +From a949b090e9d4d11c300fb23b416a2cc69483962b Mon Sep 17 00:00:00 2001 +From: George Kiagiadakis +Date: Tue, 16 Feb 2021 17:26:20 +0200 +Subject: [PATCH] modules: add new access-seclabel module + +This module allows access control based on the security label +of the client. It is tailored for use with the semantics of SMACK + +Upstream-Status: Inappropriate [smack specific] +--- + src/modules/meson.build | 10 ++ + src/modules/module-access-seclabel.c | 220 +++++++++++++++++++++++++++ + 2 files changed, 230 insertions(+) + create mode 100644 src/modules/module-access-seclabel.c + +diff --git a/src/modules/meson.build b/src/modules/meson.build +index 8c9ccc85..234cff6b 100644 +--- a/src/modules/meson.build ++++ b/src/modules/meson.build +@@ -14,6 +14,16 @@ pipewire_module_access = shared_library('pipewire-module-access', [ 'module-acce + dependencies : [mathlib, dl_lib, pipewire_dep], + ) + ++pipewire_module_access_seclabel = shared_library('pipewire-module-access-seclabel', ++ [ 'module-access-seclabel.c' ], ++ c_args : pipewire_module_c_args, ++ include_directories : [configinc, spa_inc], ++ install : true, ++ install_dir : modules_install_dir, ++ install_rpath: modules_install_dir, ++ dependencies : [mathlib, dl_lib, pipewire_dep], ++) ++ + pipewire_module_profiler = shared_library('pipewire-module-profiler', + [ 'module-profiler.c', + 'module-profiler/protocol-native.c', ], +diff --git a/src/modules/module-access-seclabel.c b/src/modules/module-access-seclabel.c +new file mode 100644 +index 00000000..3739f2e4 +--- /dev/null ++++ b/src/modules/module-access-seclabel.c +@@ -0,0 +1,220 @@ ++/* PipeWire ++ * ++ * Copyright © 2018 Wim Taymans ++ * Copyright © 2021 Collabora Ltd. ++ * @author George Kiagiadakis ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice (including the next ++ * paragraph) shall be included in all copies or substantial portions of the ++ * Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING ++ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER ++ * DEALINGS IN THE SOFTWARE. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "config.h" ++ ++#include ++#include ++ ++#include ++#include ++ ++#define NAME "access-seclabel" ++ ++#define MODULE_USAGE "[ seclabel.allowed= ] " \ ++ "[ seclabel.rejected= ] " \ ++ "[ seclabel.restricted= ] " \ ++ ++static const struct spa_dict_item module_props[] = { ++ { PW_KEY_MODULE_AUTHOR, "George Kiagiadakis " }, ++ { PW_KEY_MODULE_DESCRIPTION, "Perform access check based on the security label" }, ++ { PW_KEY_MODULE_USAGE, MODULE_USAGE }, ++ { PW_KEY_MODULE_VERSION, PACKAGE_VERSION }, ++}; ++ ++struct impl { ++ struct pw_context *context; ++ struct pw_properties *properties; ++ ++ struct spa_hook context_listener; ++ struct spa_hook module_listener; ++}; ++ ++static int check_label(const char *label, const char *str) ++{ ++ char key[1024]; ++ int res = 0; ++ struct spa_json it[2]; ++ ++ spa_json_init(&it[0], str, strlen(str)); ++ if ((res = spa_json_enter_array(&it[0], &it[1])) <= 0) ++ goto exit; ++ ++ res = 0; ++ while (spa_json_get_string(&it[1], key, sizeof(key)) > 0) { ++ if (strcmp(label, key) == 0) { ++ res = 1; ++ break; ++ } ++ } ++exit: ++ return res; ++} ++ ++static void ++context_check_access(void *data, struct pw_impl_client *client) ++{ ++ struct impl *impl = data; ++ struct pw_permission permissions[1]; ++ struct spa_dict_item items[2]; ++ const struct pw_properties *props; ++ const char *str, *access, *label = NULL; ++ int res; ++ ++ if ((props = pw_impl_client_get_properties(client)) != NULL) { ++ if ((str = pw_properties_get(props, PW_KEY_ACCESS)) != NULL) { ++ pw_log_info(NAME " client %p: has already access: '%s'", client, str); ++ return; ++ } ++ label = pw_properties_get(props, PW_KEY_SEC_LABEL); ++ } ++ ++ if (!label) { ++ pw_log_info(NAME " client %p: has no security label", client); ++ return; ++ } ++ ++ if (impl->properties && (str = pw_properties_get(impl->properties, "seclabel.allowed")) != NULL) { ++ res = check_label(label, str); ++ if (res < 0) { ++ pw_log_warn(NAME" %p: client %p allowed check failed: %s", ++ impl, client, spa_strerror(res)); ++ } else if (res > 0) { ++ access = "allowed"; ++ goto granted; ++ } ++ } ++ ++ if (impl->properties && (str = pw_properties_get(impl->properties, "seclabel.rejected")) != NULL) { ++ res = check_label(label, str); ++ if (res < 0) { ++ pw_log_warn(NAME" %p: client %p rejected check failed: %s", ++ impl, client, spa_strerror(res)); ++ } else if (res > 0) { ++ res = -EACCES; ++ access = "rejected"; ++ goto rejected; ++ } ++ } ++ ++ if (impl->properties && (str = pw_properties_get(impl->properties, "seclabel.restricted")) != NULL) { ++ res = check_label(label, str); ++ if (res < 0) { ++ pw_log_warn(NAME" %p: client %p restricted check failed: %s", ++ impl, client, spa_strerror(res)); ++ } ++ else if (res > 0) { ++ pw_log_debug(NAME" %p: restricted client %p added", impl, client); ++ access = "restricted"; ++ goto wait_permissions; ++ } ++ } ++ ++ return; ++ ++granted: ++ pw_log_info(NAME" %p: client %p '%s' access granted", impl, client, access); ++ items[0] = SPA_DICT_ITEM_INIT(PW_KEY_ACCESS, access); ++ pw_impl_client_update_properties(client, &SPA_DICT_INIT(items, 1)); ++ ++ permissions[0] = PW_PERMISSION_INIT(PW_ID_ANY, PW_PERM_ALL); ++ pw_impl_client_update_permissions(client, 1, permissions); ++ return; ++ ++wait_permissions: ++ pw_log_info(NAME " %p: client %p wait for '%s' permissions", ++ impl, client, access); ++ items[0] = SPA_DICT_ITEM_INIT(PW_KEY_ACCESS, access); ++ pw_impl_client_update_properties(client, &SPA_DICT_INIT(items, 1)); ++ return; ++ ++rejected: ++ pw_resource_error(pw_impl_client_get_core_resource(client), res, access); ++ items[0] = SPA_DICT_ITEM_INIT(PW_KEY_ACCESS, access); ++ pw_impl_client_update_properties(client, &SPA_DICT_INIT(items, 1)); ++ return; ++} ++ ++static const struct pw_context_events context_events = { ++ PW_VERSION_CONTEXT_EVENTS, ++ .check_access = context_check_access, ++}; ++ ++static void module_destroy(void *data) ++{ ++ struct impl *impl = data; ++ ++ spa_hook_remove(&impl->context_listener); ++ spa_hook_remove(&impl->module_listener); ++ ++ if (impl->properties) ++ pw_properties_free(impl->properties); ++ ++ free(impl); ++} ++ ++static const struct pw_impl_module_events module_events = { ++ PW_VERSION_IMPL_MODULE_EVENTS, ++ .destroy = module_destroy, ++}; ++ ++SPA_EXPORT ++int pipewire__module_init(struct pw_impl_module *module, const char *args) ++{ ++ struct pw_context *context = pw_impl_module_get_context(module); ++ struct pw_properties *props; ++ struct impl *impl; ++ ++ impl = calloc(1, sizeof(struct impl)); ++ if (impl == NULL) ++ return -errno; ++ ++ pw_log_debug(NAME" module %p: new %s", impl, args); ++ ++ if (args) ++ props = pw_properties_new_string(args); ++ else ++ props = NULL; ++ ++ impl->context = context; ++ impl->properties = props; ++ ++ pw_context_add_listener(context, &impl->context_listener, &context_events, impl); ++ pw_impl_module_add_listener(module, &impl->module_listener, &module_events, impl); ++ ++ pw_impl_module_update_properties(module, &SPA_DICT_INIT_ARRAY(module_props)); ++ ++ return 0; ++} +-- +2.30.0 +