From c45e6daf98199740b7fcb024d35a40b15bd805a7 Mon Sep 17 00:00:00 2001 From: Sung-Jin Park Date: Tue, 2 Jul 2019 17:08:43 +0900 Subject: [PATCH] pepper-utils: add pepper_security APIs Signed-off-by: Sung-Jin Park --- src/lib/pepper/Makefile.am | 1 + src/lib/pepper/pepper-utils.h | 9 ++ src/lib/pepper/utils-security.c | 185 ++++++++++++++++++++++++++++++++ 3 files changed, 195 insertions(+) create mode 100644 src/lib/pepper/utils-security.c diff --git a/src/lib/pepper/Makefile.am b/src/lib/pepper/Makefile.am index 52c3810..e69a0ab 100644 --- a/src/lib/pepper/Makefile.am +++ b/src/lib/pepper/Makefile.am @@ -33,6 +33,7 @@ libpepper_la_SOURCES = pepper.h \ utils-log.c \ utils-vt.c \ utils-region.c \ + utils-security.c \ subcompositor.c \ subsurface.c \ misc.c diff --git a/src/lib/pepper/pepper-utils.h b/src/lib/pepper/pepper-utils.h index bf49ba8..1b5ecae 100644 --- a/src/lib/pepper/pepper-utils.h +++ b/src/lib/pepper/pepper-utils.h @@ -974,6 +974,15 @@ PEPPER_API void pepper_region_clear(pepper_region_t *region); PEPPER_API int pepper_region_print(pepper_region_t *region); + +PEPPER_API int +pepper_security_init(void); + +PEPPER_API int +pepper_security_deinit(void); + +PEPPER_API pepper_bool_t +pepper_security_privilege_check(pid_t pid, uid_t uid, const char *privilege); #ifdef __cplusplus } #endif diff --git a/src/lib/pepper/utils-security.c b/src/lib/pepper/utils-security.c new file mode 100644 index 0000000..dd3ad39 --- /dev/null +++ b/src/lib/pepper/utils-security.c @@ -0,0 +1,185 @@ +/* +* Copyright © 2008-2012 Kristian Høgsberg +* Copyright © 2010-2012 Intel Corporation +* Copyright © 2011 Benjamin Franzke +* Copyright © 2012 Collabora, Ltd. +* Copyright © 2015 S-Core Corporation +* Copyright © 2015-2016 Samsung Electronics co., Ltd. All Rights Reserved. +* +* 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 "pepper-utils.h" + +#ifdef HAVE_CYNARA +#include +#include +#include +#include +#endif + +#ifdef HAVE_CYNARA +static cynara *g_cynara = NULL; +static int g_cynara_refcount = 0; +static int g_cynara_init_count = 0; + +static void +_pepper_security_log_print(int err, const char *fmt, ...) +{ + int ret; + va_list args; + + const int CYNARA_BUFSIZE = 128; + char buf[CYNARA_BUFSIZE] = "\0", tmp[CYNARA_BUFSIZE + CYNARA_BUFSIZE] = "\0"; + + if (fmt) { + va_start(args, fmt); + vsnprintf(tmp, CYNARA_BUFSIZE + CYNARA_BUFSIZE, fmt, args); + va_end(args); + } + + ret = cynara_strerror(err, buf, CYNARA_BUFSIZE); + + if (ret != CYNARA_API_SUCCESS) { + PEPPER_ERROR("Failed to get cynara_strerror. error : %d (error log about %s: %d)\n", ret, tmp, err); + return; + } + + PEPPER_ERROR("%s is failed. (%s)\n", tmp, buf); +} +#endif + +PEPPER_API pepper_bool_t +pepper_security_privilege_check(pid_t pid, uid_t uid, const char *privilege) +{ +#ifdef HAVE_CYNARA + pepper_bool_t res = PEPPER_FALSE; + + PEPPER_CHECK(privilege, return PEPPER_FALSE, "Invalid privilege was given.\n"); + + /* If cynara_initialize() has been (retried) and failed, we suppose that cynara is not available. */ + /* Then we return PEPPER_TRUE as if there is no security check available. */ + if (!g_cynara && g_cynara_init_count) + return PEPPER_TRUE; + + PEPPER_CHECK(g_cynara, return PEPPER_FALSE, "Pepper-security has not been initialized.\n"); + + char *client_smack = NULL; + char *client_session = NULL; + char uid_str[16] = { 0, }; + int len = -1; + int ret = -1; + + ret = smack_new_label_from_process((int)pid, &client_smack); + PEPPER_CHECK(ret > 0, goto finish, ""); + + snprintf(uid_str, 15, "%d", (int)uid); + + client_session = cynara_session_from_pid(pid); + PEPPER_CHECK(client_session, finish, ""); + + ret = cynara_check(g_cynara, + client_smack, + client_session, + uid_str, + privilege); + + if (ret == CYNARA_API_ACCESS_ALLOWED) + res = PEPPER_TRUE; + else + _pepper_security_log_print(ret, "rule: %s, client_smack: %s, pid: %d", rule, client_smack, pid); + +finish: + PEPPER_TRACE("Privilege Check For '%s' %s pid:%u uid:%u client_smack:%s(len:%d) client_session:%s ret:%d", + NULL, privilege, res ? "SUCCESS" : "FAIL", pid, uid, + client_smack ? client_smack : "N/A", len, + client_session ? client_session: "N/A", ret); + + if (client_session) + free(client_session); + if (client_smack) + free(client_smack); + + return res; +#else + return PEPPER_TRUE; +#endif +} + +PEPPER_API int +pepper_security_init(void) +{ +#ifdef HAVE_CYNARA + int ret; + int retry_cnt = 0; + static pepper_bool_t retried = PEPPER_FALSE; + + ++g_cynara_init_count; + if (++g_cynara_refcount != 1) + return g_cynara_refcount; + + if (!g_cynara && PEPPER_FALSE == retried) { + retried = PEPPER_TRUE; + + for (retry_cnt = 0; retry_cnt < 5; retry_cnt++) { + + PEPPER_TRACE("Retry cynara initialize: %d\n", retry_cnt + 1); + + ret = cynara_initialize(&g_cynara, NULL); + + if (CYNARA_API_SUCCESS == ret) { + PEPPER_TRACE("Succeed to initialize cynara !\n"); + return 1; + } + + _pepper_security_log_print(ret, "cynara_initialize"); + g_cynara = NULL; + } + } + + PEPPER_ERROR("Failed to initialize pepper_security ! (error:%d, retry_cnt=%d)\n", ret, retry_cnt); + --g_cynara_refcount; + + return 0; +#endif + return 1; +} + +PEPPER_API int +pepper_security_deinit(void) +{ +#ifdef HAVE_CYNARA + if (g_cynara_refcount < 1) + { + PEPPER_ERROR("%s called without pepper_security_init"); + return 0; + } + + if (--g_cynara_refcount != 0) + return 1; + + if (g_cynara) { + cynara_finish(g_cynara); + g_cynara = NULL; + } +#endif + return 1; +} + -- 2.34.1