From 656367df69f32d3fe530076732d8789f670de033 Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Fri, 5 Apr 2019 12:47:19 +0200 Subject: [PATCH 01/16] refactoring: make BusType a local type BusType does not need to be a global type, because in fact it is needed only to choose a correct policy checker. In the test cases, or in the command line tools we explicitly know which checker we need to choose. Thus, it is only required for the API, where we still keep it in the configuration. This will allow further simplifications. Change-Id: I61663d496279b47a6a0338b93434b5ae42326f33 --- src/dbuspolicy_serializer.cpp | 17 +++---------- src/internal/internal.h | 34 -------------------------- src/internal/naive_policy_checker.hpp | 6 ----- src/internal/policy.hpp | 1 - src/internal/serializer.cpp | 1 - src/libdbuspolicy1.cpp | 11 +++++++++ src/stest_performance.cpp | 2 -- src/test-libdbuspolicy1-access-deny-gdi.cpp | 24 ++++++++---------- src/test-libdbuspolicy1-access-deny.cpp | 8 +++--- src/test-libdbuspolicy1-ownership-deny-gdi.cpp | 1 - 10 files changed, 27 insertions(+), 78 deletions(-) delete mode 100644 src/internal/internal.h diff --git a/src/dbuspolicy_serializer.cpp b/src/dbuspolicy_serializer.cpp index deb009a..7ca1c41 100644 --- a/src/dbuspolicy_serializer.cpp +++ b/src/dbuspolicy_serializer.cpp @@ -3,7 +3,6 @@ #include #include -#include "internal/internal.h" #include "internal/serializer.hpp" #include "internal/naive_policy_checker.hpp" #include "dbuspolicy1/libdbuspolicy1.h" @@ -27,10 +26,9 @@ static void print_help(const char *name) { int main(int argc, char *argv[]) { - BusType bus_type = BusType::SYSTEM_BUS; bool need_input_filename = true; std::string output_filename; - std::string input_filename; + const char *input_filename = system_bus_conf_file_primary(); int c; while (1) { @@ -42,7 +40,7 @@ int main(int argc, char *argv[]) switch(c) { case 0: if (option_index == 1) - bus_type = BusType::SESSION_BUS; + input_filename = session_bus_conf_file_primary(); need_input_filename = false; break; case 'o': @@ -58,19 +56,10 @@ int main(int argc, char *argv[]) print_help(argv[0]); return 1; } - } else { - switch (bus_type) { - case BusType::SYSTEM_BUS: - input_filename = system_bus_conf_file_primary(); - break; - case BusType::SESSION_BUS: - input_filename = session_bus_conf_file_primary(); - break; - } } if (output_filename.empty()) - output_filename = input_filename + ".serialized"; + output_filename = std::string(input_filename) + ".serialized"; cout << "Read from: " << input_filename << " write to: " << output_filename << endl; ldp_xml_parser::Serializer serializer; diff --git a/src/internal/internal.h b/src/internal/internal.h deleted file mode 100644 index 9cd1516..0000000 --- a/src/internal/internal.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ - - -/** - \defgroup Implementation Implementation - Internal implementation of policy. - */ -/** - * \file - * \ingroup Implementation - */ -#ifndef _LIBDBUSPOLICY1_INTERNAL_H_ -#define _LIBDBUSPOLICY1_INTERNAL_H_ - -typedef enum { - SYSTEM_BUS = 0, - SESSION_BUS = 1 -} BusType; - -#endif diff --git a/src/internal/naive_policy_checker.hpp b/src/internal/naive_policy_checker.hpp index baf1b85..d92fba2 100644 --- a/src/internal/naive_policy_checker.hpp +++ b/src/internal/naive_policy_checker.hpp @@ -138,10 +138,4 @@ namespace ldp_xml_parser DCL_NODESTRUCT_GLOBAL(ldp_xml_parser::NaivePolicyChecker, policy_checker_system) DCL_NODESTRUCT_GLOBAL(ldp_xml_parser::NaivePolicyChecker, policy_checker_session) -inline ldp_xml_parser::NaivePolicyChecker &policy_checker(BusType bus_type) { - if (SESSION_BUS == bus_type) - return policy_checker_session(); - return policy_checker_system(); -} - #endif diff --git a/src/internal/policy.hpp b/src/internal/policy.hpp index f7593b2..51a4322 100644 --- a/src/internal/policy.hpp +++ b/src/internal/policy.hpp @@ -25,7 +25,6 @@ #include "type_list.h" #include "bus_names_array.hpp" -#include "internal.h" #include #include diff --git a/src/internal/serializer.cpp b/src/internal/serializer.cpp index 869a718..578157a 100644 --- a/src/internal/serializer.cpp +++ b/src/internal/serializer.cpp @@ -15,7 +15,6 @@ */ #include "include/fb_generated.h" #include "include/flatbuffers/flatbuffers.h" -#include "internal.h" #include "naive_policy_checker.hpp" #include "serializer.hpp" #include "tslog.hpp" diff --git a/src/libdbuspolicy1.cpp b/src/libdbuspolicy1.cpp index a2fdde4..c15aebd 100644 --- a/src/libdbuspolicy1.cpp +++ b/src/libdbuspolicy1.cpp @@ -44,6 +44,11 @@ using ldp_xml_parser::MatchItemSend; using ldp_xml_parser::MatchItemReceive; using ldp_xml_parser::MatchItemOwn; +typedef enum { + SYSTEM_BUS = 0, + SESSION_BUS = 1 +} BusType; + struct kconn { KdbusConnection conn; BusType bus_type; @@ -59,6 +64,12 @@ static std::once_flag init_once_done; static std::once_flag init_once_db[2]; static std::once_flag init_once_conn[2]; +inline ldp_xml_parser::NaivePolicyChecker &policy_checker(BusType bus_type) { + if (SESSION_BUS == bus_type) + return policy_checker_session(); + return policy_checker_system(); +} + extern "C" void __dbuspolicy1_change_creds(uid_t uid, gid_t gid, const char* label) { g_udesc.uid = uid; diff --git a/src/stest_performance.cpp b/src/stest_performance.cpp index 9b2e7ba..2f1c643 100644 --- a/src/stest_performance.cpp +++ b/src/stest_performance.cpp @@ -1,5 +1,4 @@ #include "internal/include/fb_generated.h" -#include "internal/internal.h" #include "internal/naive_policy_checker.hpp" #include "internal/policy.hpp" #include "internal/serializer.hpp" @@ -7,7 +6,6 @@ #include "internal/storage_backend_serialized.hpp" #include "internal/tslog.hpp" #include "libdbuspolicy1-private.h" -#include #include #include #include diff --git a/src/test-libdbuspolicy1-access-deny-gdi.cpp b/src/test-libdbuspolicy1-access-deny-gdi.cpp index 5b35919..dbad42a 100644 --- a/src/test-libdbuspolicy1-access-deny-gdi.cpp +++ b/src/test-libdbuspolicy1-access-deny-gdi.cpp @@ -1,5 +1,4 @@ #include "internal/include/fb_generated.h" -#include "internal/internal.h" #include "internal/naive_policy_checker.hpp" #include "internal/policy.hpp" #include "internal/serializer.hpp" @@ -89,11 +88,8 @@ void print_test(const struct AccessTest* t, bool result) { } template -bool run_tests_for_bus(const DB &db, const BusType bus_type, const std::vector& test_setup, int& i, bool& passed) { - +bool run_tests_for_bus(const DB &db, NaivePolicyChecker &checker, const std::vector& test_setup, int& i, bool& passed) { for (const auto& test : test_setup) { - auto &checker = policy_checker(bus_type); - checker.updateGroupDb(test.user, test.group); const auto &gids = *checker.getGroups(test.user, test.group); @@ -125,17 +121,17 @@ bool run_policy_db(const std::pair access_test) { const auto& system_bus_setup = access_test.first; const auto& session_bus_setup = access_test.second; - policy_checker_system().initDb(system_bus_setup.first.c_str()); + auto &checker_system = policy_checker_system(); + auto &checker_session = policy_checker_session(); + + checker_system.initDb(system_bus_setup.first.c_str()); if (session_bus_setup.first != "") { - policy_checker_session().initDb(session_bus_setup.first.c_str()); + checker_session.initDb(session_bus_setup.first.c_str()); } - auto *sys_db = &policy_checker_system().getPolicyDb(); - auto *ses_db = &policy_checker_session().getPolicyDb(); - printf("POLICY_DB:\n"); - return run_tests_for_bus(*sys_db, SYSTEM_BUS, system_bus_setup.second, i, passed) && - run_tests_for_bus(*ses_db, SESSION_BUS, session_bus_setup.second, i, passed); + return run_tests_for_bus(checker_system.getPolicyDb(), checker_system, system_bus_setup.second, i, passed) && + run_tests_for_bus(checker_session.getPolicyDb(), checker_session, session_bus_setup.second, i, passed); } bool run_fb(const std::pair access_test) { @@ -159,12 +155,12 @@ bool run_fb(const std::pair access_test) { const FB::File *file_sys = FB::GetFile(buff_sys); storage_sys.init(file_sys); - bool res = run_tests_for_bus(storage_sys, SYSTEM_BUS, system_bus_setup.second, i, passed); + bool res = run_tests_for_bus(storage_sys, policy_checker_system(), system_bus_setup.second, i, passed); if (buff_ses) { const FB::File *file_ses = FB::GetFile(buff_ses); storage_ses.init(file_ses); - res &= run_tests_for_bus(storage_ses, SESSION_BUS, session_bus_setup.second, i, passed); + res &= run_tests_for_bus(storage_ses, policy_checker_session(), session_bus_setup.second, i, passed); } return res; } diff --git a/src/test-libdbuspolicy1-access-deny.cpp b/src/test-libdbuspolicy1-access-deny.cpp index d74144e..e7e80af 100644 --- a/src/test-libdbuspolicy1-access-deny.cpp +++ b/src/test-libdbuspolicy1-access-deny.cpp @@ -1,4 +1,3 @@ -#include "internal/internal.h" #include "internal/naive_policy_checker.hpp" #include "internal/tslog.hpp" #include @@ -81,9 +80,8 @@ void print_test(const struct AccessTest* t, DecisionResult result) { DECISIONS[t->expected_result], DECISIONS[result]); } -void run_tests_for_bus(BusType bus_type, const std::vector& test_setup, int& i, bool& passed) { +void run_tests_for_bus(ldp_xml_parser::NaivePolicyChecker &checker, const std::vector& test_setup, int& i, bool& passed) { for (const auto& test : test_setup) { - auto &checker = policy_checker(bus_type); checker.updateGroupDb(test.user, test.group); auto decision = checker.check(bus_owner, test.user, test.group, test.label); if (decision != test.expected_result) { @@ -109,8 +107,8 @@ bool run_access_tests() { policy_checker_session().initDb(session_bus_setup.first.c_str()); } - run_tests_for_bus(SYSTEM_BUS, system_bus_setup.second, i, passed); - run_tests_for_bus(SESSION_BUS, session_bus_setup.second, i, passed); + run_tests_for_bus(policy_checker_system(), system_bus_setup.second, i, passed); + run_tests_for_bus(policy_checker_session(), session_bus_setup.second, i, passed); } return passed; } diff --git a/src/test-libdbuspolicy1-ownership-deny-gdi.cpp b/src/test-libdbuspolicy1-ownership-deny-gdi.cpp index a4f7f67..3d86a31 100644 --- a/src/test-libdbuspolicy1-ownership-deny-gdi.cpp +++ b/src/test-libdbuspolicy1-ownership-deny-gdi.cpp @@ -1,5 +1,4 @@ #include "internal/include/fb_generated.h" -#include "internal/internal.h" #include "internal/naive_policy_checker.hpp" #include "internal/policy.hpp" #include "internal/serializer.hpp" -- 2.7.4 From bc3c05a72c339ef61e8590bdee03d6e93226a10f Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Fri, 5 Apr 2019 13:20:59 +0200 Subject: [PATCH 02/16] refactoring: use checker directly instead BusType in configuration This makes configuration use pointer to checker in place of previously used BusType. This way on queries, the object is used throught the pointer instead of selecting correct checker with yet another 'if' clause. Change-Id: I79f129be899ff501a01ff1fbf1a95c5d194e3abf --- src/libdbuspolicy1.cpp | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/libdbuspolicy1.cpp b/src/libdbuspolicy1.cpp index c15aebd..94dfdfa 100644 --- a/src/libdbuspolicy1.cpp +++ b/src/libdbuspolicy1.cpp @@ -51,7 +51,7 @@ typedef enum { struct kconn { KdbusConnection conn; - BusType bus_type; + ldp_xml_parser::NaivePolicyChecker *checker; } g_conn[2]; struct udesc { @@ -202,7 +202,7 @@ static void init_common_locked(BusType bus_type) static void init_global_conn_locked(BusType bus_type, std::shared_ptr resolved_path) { struct kconn *kconn = &g_conn[bus_type]; - kconn->bus_type = bus_type; + kconn->checker = &policy_checker(bus_type); if (kconn->conn.connect(resolved_path.get(), 0, _KDBUS_ATTACH_ALL, 0) < 0) { assert(false && "failed kdbus_connect"); @@ -224,7 +224,7 @@ static kconn *init_shared_fd(BusType bus_type, int fd) return nullptr; } result->conn.shared_init_fd(fd); - result->bus_type = bus_type; + result->checker = &policy_checker(bus_type); return result; } @@ -336,7 +336,7 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration, auto m_type = toMessageType(message_type); MatchItemSend sendItem(interface, member, path, m_type, destinationInfo.names()); - auto decision = policy_checker(kconn->bus_type).check(g_udesc.uid, g_udesc.gid, g_udesc.label, sendItem); + auto decision = kconn->checker->check(g_udesc.uid, g_udesc.gid, g_udesc.label, sendItem); if (DecisionResult::ALLOW != decision) return decisionToRetCode(decision); @@ -349,10 +349,10 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration, return r; MatchItemReceive receiveItem(interface, member, path, m_type, senderInfo.names()); - return decisionToRetCode(policy_checker(kconn->bus_type).check(destinationInfo.uid(), - destinationInfo.gid(), - destinationInfo.label(), - receiveItem)); + return decisionToRetCode(kconn->checker->check(destinationInfo.uid(), + destinationInfo.gid(), + destinationInfo.label(), + receiveItem)); } DBUSPOLICY1_EXPORT int dbuspolicy1_check_in(void* configuration, @@ -380,7 +380,7 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_in(void* configuration, auto m_type = toMessageType(message_type); MatchItemSend sendItem(interface, member, path, m_type, info.names()); - auto decision = policy_checker(kconn->bus_type).check(sender_uid, sender_gid, sender_label, sendItem); + auto decision = kconn->checker->check(sender_uid, sender_gid, sender_label, sendItem); if (DecisionResult::ALLOW != decision) return decisionToRetCode(decision); @@ -392,18 +392,18 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_in(void* configuration, KdbusBusNames names; MatchItemReceive receiveItem(interface, member, path, m_type, names.addSpaceSeparatedNames(sender)); - return decisionToRetCode(policy_checker(kconn->bus_type).check(g_udesc.uid, - g_udesc.gid, - g_udesc.label, - receiveItem)); + return decisionToRetCode(kconn->checker->check(g_udesc.uid, + g_udesc.gid, + g_udesc.label, + receiveItem)); } DBUSPOLICY1_EXPORT int dbuspolicy1_can_own(void* configuration, const char* const service) { tslog::LogLock log_lock; auto kconn = KCONN(configuration); - return decisionToRetCode(policy_checker(kconn->bus_type).check(g_udesc.uid, - g_udesc.gid, - g_udesc.label, - MatchItemOwn(service))); + return decisionToRetCode(kconn->checker->check(g_udesc.uid, + g_udesc.gid, + g_udesc.label, + MatchItemOwn(service))); } -- 2.7.4 From c150649fb8a1b6c79837fb4165f37095630eb817 Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Wed, 10 Apr 2019 14:37:33 +0200 Subject: [PATCH 03/16] refactoring: getNames() -> prepareNames() prepareNames() is more proper name for the function as it prepares an array of names in the KdbusConnectionInfo object, it does not return them. Change-Id: I9f86ae80c138a2371456c86543757e962d23e25a --- src/libdbuspolicy1.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/libdbuspolicy1.cpp b/src/libdbuspolicy1.cpp index 94dfdfa..6fe1722 100644 --- a/src/libdbuspolicy1.cpp +++ b/src/libdbuspolicy1.cpp @@ -286,7 +286,13 @@ DBUSPOLICY1_EXPORT void dbuspolicy1_free(void* configuration) delete KCONN(configuration); } -static int getNames(const char *name, KdbusConnectionInfo &info, +/* + * This function prepares contents of info.names() for initialization of MatchItems. + * First, it tries to get names from kdbus connection. + * If it fails, names are added from the 'name' parameter, which is treaten + * as a string containing names separated by single space. + */ +static int prepareNames(const char *name, KdbusConnectionInfo &info, KdbusConnection::conn_info_type info_type) { if (name && *name) { int r = info.get(name, info_type); @@ -329,7 +335,7 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration, int r; /* check can send */ /* if broadcasting, then pass - null destination */ - r = getNames(destination, destinationInfo, KdbusConnection::POLICY_CONN_INFO_ALL); + r = prepareNames(destination, destinationInfo, KdbusConnection::POLICY_CONN_INFO_ALL); if (r < 0) return r; @@ -344,7 +350,7 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration, KdbusConnectionInfo senderInfo(kconn->conn); /* check can recv */ /* get sender information from kdbus */ - r = getNames(sender, senderInfo, KdbusConnection::POLICY_CONN_INFO_NAME); + r = prepareNames(sender, senderInfo, KdbusConnection::POLICY_CONN_INFO_NAME); if (r < 0) return r; @@ -373,7 +379,7 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_in(void* configuration, auto kconn = KCONN(configuration); KdbusConnectionInfo info(kconn->conn); int r; - r = getNames(destination, info, KdbusConnection::POLICY_CONN_INFO_NAME); + r = prepareNames(destination, info, KdbusConnection::POLICY_CONN_INFO_NAME); if (r < 0) return r; -- 2.7.4 From f672317725839513e92cba5faa4712aaddc6cd94 Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Wed, 10 Apr 2019 15:02:42 +0200 Subject: [PATCH 04/16] refactoring: group g_udesc operations into a struct Change-Id: I474a61e811cb7eb316ad8b57c298b8730f74eb25 --- src/libdbuspolicy1.cpp | 91 +++++++++++++++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 38 deletions(-) diff --git a/src/libdbuspolicy1.cpp b/src/libdbuspolicy1.cpp index 6fe1722..812363e 100644 --- a/src/libdbuspolicy1.cpp +++ b/src/libdbuspolicy1.cpp @@ -49,56 +49,70 @@ typedef enum { SESSION_BUS = 1 } BusType; -struct kconn { - KdbusConnection conn; - ldp_xml_parser::NaivePolicyChecker *checker; -} g_conn[2]; - +/* + * This is a global structure that gets and keeps credentials from the current process, + * as they are needed for every policy checking operation. + */ struct udesc { uid_t uid; gid_t gid; char label[256]; -} g_udesc; -static std::once_flag init_once_done; -static std::once_flag init_once_db[2]; -static std::once_flag init_once_conn[2]; + void init() { + std::call_once(init_once_done, std::bind(&udesc::init_once, this)); + } -inline ldp_xml_parser::NaivePolicyChecker &policy_checker(BusType bus_type) { - if (SESSION_BUS == bus_type) - return policy_checker_session(); - return policy_checker_system(); -} + void change_creds(uid_t uid_, gid_t gid_, const char *label_) + { + uid = uid_; + gid = gid_; + if (label_) + strncpy(label, label_, strlen(label_) + 1); + } + +private: + std::once_flag init_once_done; + void init_once() + { + char buf[1024]; + int attr_fd; + int r; + + attr_fd = open("/proc/self/attr/current", O_RDONLY); + if (attr_fd < 0) + assert(false && "failed open: /proc/self/attr/current"); + r = read(attr_fd, buf, sizeof(buf)); + close(attr_fd); + + if (r < 0 || r >= (long int)sizeof(label)) /* read */ + assert(false && "failed read: /proc/self/attr/current"); + buf[r] = 0; + + uid = getuid(); + gid = getgid(); + snprintf(label, r + 1 /* additional byte for \0 */, "%s", buf); + + tslog::init(); + } +} g_udesc; extern "C" void __dbuspolicy1_change_creds(uid_t uid, gid_t gid, const char* label) { - g_udesc.uid = uid; - g_udesc.gid = gid; - if (label) - strncpy(g_udesc.label, label, strlen(label) + 1); + g_udesc.change_creds(uid, gid, label); } -static void dbuspolicy_init_once_locked(void) -{ - char buf[1024]; - int attr_fd; - int r; - - attr_fd = open("/proc/self/attr/current", O_RDONLY); - if (attr_fd < 0) - assert(false && "failed open: /proc/self/attr/current"); - r = read(attr_fd, buf, sizeof(buf)); - close(attr_fd); - - if (r < 0 || r >= (long int)sizeof(g_udesc.label)) /* read */ - assert(false && "failed read: /proc/self/attr/current"); - buf[r] = 0; +struct kconn { + KdbusConnection conn; + ldp_xml_parser::NaivePolicyChecker *checker; +} g_conn[2]; - g_udesc.uid = getuid(); - g_udesc.gid = getgid(); - snprintf(g_udesc.label, r + 1 /* additional byte for \0 */, "%s", buf); +static std::once_flag init_once_db[2]; +static std::once_flag init_once_conn[2]; - tslog::init(); +inline ldp_xml_parser::NaivePolicyChecker &policy_checker(BusType bus_type) { + if (SESSION_BUS == bus_type) + return policy_checker_session(); + return policy_checker_system(); } static std::shared_ptr bus_type_from_path(const char *bus_path, BusType &bus_type) @@ -230,7 +244,6 @@ static kconn *init_shared_fd(BusType bus_type, int fd) static DecisionResult can_open(BusType bus_type, uid_t bus_owner) noexcept { - std::call_once(init_once_done, dbuspolicy_init_once_locked); std::call_once(init_once_db[bus_type], init_common_locked, bus_type); return policy_checker(bus_type).check(bus_owner, g_udesc.uid, g_udesc.gid, g_udesc.label); @@ -250,6 +263,8 @@ DBUSPOLICY1_EXPORT void* dbuspolicy1_init_shared(const char *bus_path, int fd) return nullptr; } + g_udesc.init(); + struct kconn *result = nullptr; if (can_open(bus_type, bus_owner) == DecisionResult::ALLOW) { if (-1 == fd) { -- 2.7.4 From d71fdc32316b5d0d2b1d4fa284465f20e3ab6578 Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Wed, 10 Apr 2019 16:22:21 +0200 Subject: [PATCH 05/16] refactoring: group checker functions into a class This introduces local Checker class that helps with initializing and selecting NaivePolicyChecker instances. Change-Id: Ia859e63903b4ea173fe4cae5de9cfadc1aa94d4a --- src/libdbuspolicy1.cpp | 100 +++++++++++++++++++++++++------------------------ 1 file changed, 52 insertions(+), 48 deletions(-) diff --git a/src/libdbuspolicy1.cpp b/src/libdbuspolicy1.cpp index 812363e..eb8a802 100644 --- a/src/libdbuspolicy1.cpp +++ b/src/libdbuspolicy1.cpp @@ -43,6 +43,7 @@ using ldp_xml_parser::DecisionResult; using ldp_xml_parser::MatchItemSend; using ldp_xml_parser::MatchItemReceive; using ldp_xml_parser::MatchItemOwn; +using ldp_xml_parser::NaivePolicyChecker; typedef enum { SYSTEM_BUS = 0, @@ -101,20 +102,61 @@ extern "C" void __dbuspolicy1_change_creds(uid_t uid, gid_t gid, const char* lab g_udesc.change_creds(uid, gid, label); } +/* + * This class decorates NaivePolicyChecker with initialization mechanisms. + * Thread-safety is ensured by C++ and static initialization in static member functions. + */ +class Checker { +public: + Checker(NaivePolicyChecker &checker, const char *primary_file_name, const char *secondary_file_name) + : _checker{checker} + { + std::string primary_file_name_serialized = primary_file_name; + primary_file_name_serialized.append(".serialized"); + + auto ok = _checker.initDb(primary_file_name, primary_file_name_serialized.c_str()); + if (!ok) + ok = _checker.initDb(secondary_file_name); + + assert(ok && "failed database initialization"); + + _checker.updateGroupDb(g_udesc.uid, g_udesc.gid); + } + + NaivePolicyChecker &checker() { return _checker; } + + // this checks if this process can open a bus owned by bus_owner + inline bool can_open_owned_by(uid_t bus_owner) { + return _checker.check(bus_owner, g_udesc.uid, g_udesc.gid, g_udesc.label) == DecisionResult::ALLOW; + } + + static Checker &system() { + static Checker checker{policy_checker_system(), system_bus_conf_file_primary(), SYSTEM_BUS_CONF_FILE_SECONDARY}; + return checker; + } + + static Checker &session() { + static Checker checker{policy_checker_session(), session_bus_conf_file_primary(), SESSION_BUS_CONF_FILE_SECONDARY}; + return checker; + } + + static inline Checker &get(BusType bus_type) { + if (SESSION_BUS == bus_type) + return session(); + return system(); + } + +private: + NaivePolicyChecker &_checker; +}; + struct kconn { KdbusConnection conn; ldp_xml_parser::NaivePolicyChecker *checker; } g_conn[2]; -static std::once_flag init_once_db[2]; static std::once_flag init_once_conn[2]; -inline ldp_xml_parser::NaivePolicyChecker &policy_checker(BusType bus_type) { - if (SESSION_BUS == bus_type) - return policy_checker_session(); - return policy_checker_system(); -} - static std::shared_ptr bus_type_from_path(const char *bus_path, BusType &bus_type) { assert(bus_path); @@ -182,41 +224,10 @@ static std::shared_ptr bus_path_resolve(const char *bus_path, BusTyp return resolved_path; } -static const char *primary_conf_file(BusType bus_type) -{ - if (SYSTEM_BUS == bus_type) - return system_bus_conf_file_primary(); - return session_bus_conf_file_primary(); -} - -static const char *secondary_conf_file(BusType bus_type) -{ - if (SYSTEM_BUS == bus_type) - return SYSTEM_BUS_CONF_FILE_SECONDARY; - return SESSION_BUS_CONF_FILE_SECONDARY; -} - -static void init_common_locked(BusType bus_type) -{ - auto primary_file_name = primary_conf_file(bus_type); - std::string primary_file_name_serialized = primary_file_name; - primary_file_name_serialized.append(".serialized"); - - auto &checker = policy_checker(bus_type); - - auto ok = checker.initDb(primary_file_name, primary_file_name_serialized.c_str()); - if (!ok) - ok = checker.initDb(secondary_conf_file(bus_type)); - - assert(ok && "failed database initialization"); - - checker.updateGroupDb(g_udesc.uid, g_udesc.gid); -} - static void init_global_conn_locked(BusType bus_type, std::shared_ptr resolved_path) { struct kconn *kconn = &g_conn[bus_type]; - kconn->checker = &policy_checker(bus_type); + kconn->checker = &Checker::get(bus_type).checker(); if (kconn->conn.connect(resolved_path.get(), 0, _KDBUS_ATTACH_ALL, 0) < 0) { assert(false && "failed kdbus_connect"); @@ -238,17 +249,10 @@ static kconn *init_shared_fd(BusType bus_type, int fd) return nullptr; } result->conn.shared_init_fd(fd); - result->checker = &policy_checker(bus_type); + result->checker = &Checker::get(bus_type).checker(); return result; } -static DecisionResult can_open(BusType bus_type, uid_t bus_owner) noexcept -{ - std::call_once(init_once_db[bus_type], init_common_locked, bus_type); - - return policy_checker(bus_type).check(bus_owner, g_udesc.uid, g_udesc.gid, g_udesc.label); -} - DBUSPOLICY1_EXPORT void* dbuspolicy1_init_shared(const char *bus_path, int fd) { static_assert(SYSTEM_BUS == 0, "SYSTEM_BUS not 0"); @@ -266,7 +270,7 @@ DBUSPOLICY1_EXPORT void* dbuspolicy1_init_shared(const char *bus_path, int fd) g_udesc.init(); struct kconn *result = nullptr; - if (can_open(bus_type, bus_owner) == DecisionResult::ALLOW) { + if (Checker::get(bus_type).can_open_owned_by(bus_owner)) { if (-1 == fd) { result = get_global_conn(bus_type, resolved_path); } else { -- 2.7.4 From 366fdf52afc17355e024c493c5421abf5f63278d Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Wed, 10 Apr 2019 16:25:24 +0200 Subject: [PATCH 06/16] refactoring: group kconn ops into a class This moves functions dealing with kconn into the kconn class. Change-Id: I27422ae661071ec33d27bced8b2954ea744d16d0 --- src/libdbuspolicy1.cpp | 133 ++++++++++++++++++++++++++++--------------------- 1 file changed, 75 insertions(+), 58 deletions(-) diff --git a/src/libdbuspolicy1.cpp b/src/libdbuspolicy1.cpp index eb8a802..f6cf758 100644 --- a/src/libdbuspolicy1.cpp +++ b/src/libdbuspolicy1.cpp @@ -150,12 +150,63 @@ private: NaivePolicyChecker &_checker; }; -struct kconn { +/* + * kconn is a class which binds together a kdbus connection and a corresponding policy checker. + * It has two flavors: + * - global objects for system bus and session bus with private connections (static get() method); + * - objects created on demand when a client shares his kdbus connection with the library (static get_shared() method). + * + * Because the pointer to such object is passed (through void *) to a client, and then clients + * pass the pointer to dbuspolicy1_* functions, we always need to maintain the same type, + * regardless of the flavor. + * + * Thread-safety is ensured by C++ and static initialization in static member functions. + */ +class kconn { +public: KdbusConnection conn; - ldp_xml_parser::NaivePolicyChecker *checker; -} g_conn[2]; + NaivePolicyChecker &checker; + bool can_be_freed; -static std::once_flag init_once_conn[2]; + kconn(NaivePolicyChecker &ch, const char *resolved_path) + : checker{ch}, can_be_freed{false} + { + if (conn.connect(resolved_path, 0, _KDBUS_ATTACH_ALL, 0) < 0) { + assert(false && "failed kdbus_connect"); + } + } + + kconn(NaivePolicyChecker &ch, int fd) + : checker{ch}, can_be_freed{true} + { + conn.shared_init_fd(fd); + } + + static inline kconn &get(BusType bus_type, const char *resolved_path) { + if (SYSTEM_BUS == bus_type) + return system(resolved_path); + return session(resolved_path); + } + + static inline kconn *get_shared(BusType bus_type, int fd) + { + kconn *result = new kconn(Checker::get(bus_type).checker(), fd); + if (nullptr == result) + LOGE("Error: failed to allocate memory for policy configuration"); + return result; + } + +private: + static kconn &system(const char *resolved_path) { + static kconn c{Checker::system().checker(), resolved_path}; + return c; + } + static kconn &session(const char *resolved_path) { + static kconn c{Checker::session().checker(), resolved_path}; + return c; + } + +}; static std::shared_ptr bus_type_from_path(const char *bus_path, BusType &bus_type) { @@ -224,40 +275,8 @@ static std::shared_ptr bus_path_resolve(const char *bus_path, BusTyp return resolved_path; } -static void init_global_conn_locked(BusType bus_type, std::shared_ptr resolved_path) -{ - struct kconn *kconn = &g_conn[bus_type]; - kconn->checker = &Checker::get(bus_type).checker(); - - if (kconn->conn.connect(resolved_path.get(), 0, _KDBUS_ATTACH_ALL, 0) < 0) { - assert(false && "failed kdbus_connect"); - } -} - -static struct kconn *get_global_conn(BusType bus_type, std::shared_ptr resolved_path) noexcept -{ - std::call_once(init_once_conn[bus_type], init_global_conn_locked, bus_type, resolved_path); - - return &g_conn[bus_type]; -} - -static kconn *init_shared_fd(BusType bus_type, int fd) -{ - kconn *result = new kconn; - if (nullptr == result) { - LOGE("Error: failed to allocate memory for policy configuration"); - return nullptr; - } - result->conn.shared_init_fd(fd); - result->checker = &Checker::get(bus_type).checker(); - return result; -} - DBUSPOLICY1_EXPORT void* dbuspolicy1_init_shared(const char *bus_path, int fd) { - static_assert(SYSTEM_BUS == 0, "SYSTEM_BUS not 0"); - static_assert(SESSION_BUS == 1, "SESSION_BUS not 1"); - BusType bus_type = SESSION_BUS; uid_t bus_owner = 0; @@ -269,12 +288,12 @@ DBUSPOLICY1_EXPORT void* dbuspolicy1_init_shared(const char *bus_path, int fd) g_udesc.init(); - struct kconn *result = nullptr; + kconn *result = nullptr; if (Checker::get(bus_type).can_open_owned_by(bus_owner)) { if (-1 == fd) { - result = get_global_conn(bus_type, resolved_path); + result = &kconn::get(bus_type, resolved_path.get()); } else { - result = init_shared_fd(bus_type, fd); + result = kconn::get_shared(bus_type, fd); } } @@ -298,11 +317,9 @@ DBUSPOLICY1_EXPORT void dbuspolicy1_init_set_pool(void *configuration, void *poo DBUSPOLICY1_EXPORT void dbuspolicy1_free(void* configuration) { - for (size_t i = 0; i < sizeof(g_conn)/sizeof(g_conn[0]); i++) - if (configuration == &g_conn[i]) - return; - - delete KCONN(configuration); + auto kconn = KCONN(configuration); + if (kconn->can_be_freed) + delete kconn; } /* @@ -361,7 +378,7 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration, auto m_type = toMessageType(message_type); MatchItemSend sendItem(interface, member, path, m_type, destinationInfo.names()); - auto decision = kconn->checker->check(g_udesc.uid, g_udesc.gid, g_udesc.label, sendItem); + auto decision = kconn->checker.check(g_udesc.uid, g_udesc.gid, g_udesc.label, sendItem); if (DecisionResult::ALLOW != decision) return decisionToRetCode(decision); @@ -374,10 +391,10 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration, return r; MatchItemReceive receiveItem(interface, member, path, m_type, senderInfo.names()); - return decisionToRetCode(kconn->checker->check(destinationInfo.uid(), - destinationInfo.gid(), - destinationInfo.label(), - receiveItem)); + return decisionToRetCode(kconn->checker.check(destinationInfo.uid(), + destinationInfo.gid(), + destinationInfo.label(), + receiveItem)); } DBUSPOLICY1_EXPORT int dbuspolicy1_check_in(void* configuration, @@ -405,7 +422,7 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_in(void* configuration, auto m_type = toMessageType(message_type); MatchItemSend sendItem(interface, member, path, m_type, info.names()); - auto decision = kconn->checker->check(sender_uid, sender_gid, sender_label, sendItem); + auto decision = kconn->checker.check(sender_uid, sender_gid, sender_label, sendItem); if (DecisionResult::ALLOW != decision) return decisionToRetCode(decision); @@ -417,18 +434,18 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_in(void* configuration, KdbusBusNames names; MatchItemReceive receiveItem(interface, member, path, m_type, names.addSpaceSeparatedNames(sender)); - return decisionToRetCode(kconn->checker->check(g_udesc.uid, - g_udesc.gid, - g_udesc.label, - receiveItem)); + return decisionToRetCode(kconn->checker.check(g_udesc.uid, + g_udesc.gid, + g_udesc.label, + receiveItem)); } DBUSPOLICY1_EXPORT int dbuspolicy1_can_own(void* configuration, const char* const service) { tslog::LogLock log_lock; auto kconn = KCONN(configuration); - return decisionToRetCode(kconn->checker->check(g_udesc.uid, - g_udesc.gid, - g_udesc.label, - MatchItemOwn(service))); + return decisionToRetCode(kconn->checker.check(g_udesc.uid, + g_udesc.gid, + g_udesc.label, + MatchItemOwn(service))); } -- 2.7.4 From befaa9f2b51f8da01fa34f3cc07540fe207fc6d4 Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Wed, 10 Apr 2019 16:04:13 +0200 Subject: [PATCH 07/16] refactoring: group path resolving ops into a class This introduces BusPathResolver class. Change-Id: I56d22e0b6b5e565415b1ff6d070986efa97c7502 --- src/libdbuspolicy1.cpp | 129 ++++++++++++++++++++++++------------------------- 1 file changed, 62 insertions(+), 67 deletions(-) diff --git a/src/libdbuspolicy1.cpp b/src/libdbuspolicy1.cpp index f6cf758..394e685 100644 --- a/src/libdbuspolicy1.cpp +++ b/src/libdbuspolicy1.cpp @@ -36,9 +36,6 @@ #include #include -#define KDBUS_PATH_PREFIX "/sys/fs/kdbus/" -#define KDBUS_SYSTEM_BUS_PATH KDBUS_PATH_PREFIX"0-system/bus" - using ldp_xml_parser::DecisionResult; using ldp_xml_parser::MatchItemSend; using ldp_xml_parser::MatchItemReceive; @@ -208,90 +205,88 @@ private: }; -static std::shared_ptr bus_type_from_path(const char *bus_path, BusType &bus_type) -{ - assert(bus_path); - - std::shared_ptr p(realpath(bus_path, nullptr), [](const char *a) { free(const_cast(a)); }); - if (!p) - return nullptr; - - if (0 == strcmp(p.get(), KDBUS_SYSTEM_BUS_PATH)) { - bus_type = SYSTEM_BUS; - return p; - } - - if (0 == strncmp(p.get(), KDBUS_PATH_PREFIX, strlen(KDBUS_PATH_PREFIX))) { - bus_type = SESSION_BUS; - return p; - } - - return nullptr; -} - -// We will never get 0 as a session bus owner (0 uses "0-system" bus), -// so it's OK to assume that bus_owner==0 always means error. -static uid_t bus_owner_from_path(const char *resolved_path) noexcept -{ - boost::string_ref user_suffix("-user/bus"); - boost::string_ref ps(resolved_path); - - if (!ps.ends_with(user_suffix)) - return 0; - - ps.remove_suffix(user_suffix.length()); - - size_t last_slash = ps.find_last_of('/'); - if (last_slash == boost::string_ref::npos || last_slash == ps.length() - 1) - return 0; - - ps = ps.substr(last_slash+1); +/* + * This class encapsulates functions used to analyze passed path to kdbus bus file. + * It recognizes system and session paths. + * If it recognizes path as a session bus, then it extracts owner's uid. + */ +class BusPathResolver { + std::shared_ptr resolved_path; + BusType type{SESSION_BUS}; + uid_t owner{0}; + bool ok{false}; + + // We will never get 0 as a session bus owner (0 uses "0-system" bus), + // so it's OK to assume that bus_owner==0 always means error. + bool extract_bus_owner() noexcept + { + boost::string_ref user_suffix("-user/bus"); + boost::string_ref ps(resolved_path.get()); - errno = 0; - uid_t bus_owner = strtol(ps.data(), NULL, 10); - if (errno) - return 0; + if (!ps.ends_with(user_suffix)) + return false; - return bus_owner; -} + ps.remove_suffix(user_suffix.length()); -static std::shared_ptr bus_path_resolve(const char *bus_path, BusType &bus_type, uid_t &bus_owner) -{ - assert(bus_path); + size_t last_slash = ps.find_last_of('/'); + if (last_slash == boost::string_ref::npos || last_slash == ps.length() - 1) + return false; - auto resolved_path = bus_type_from_path(bus_path, bus_type); + ps = ps.substr(last_slash+1); - if (nullptr == resolved_path) - return nullptr; + errno = 0; + uid_t bus_owner = strtol(ps.data(), NULL, 10); + if (errno) + return false; - if (bus_type == SESSION_BUS) { - auto result = bus_owner_from_path(resolved_path.get()); - if (result > 0) - bus_owner = result; - else - return nullptr; + owner = bus_owner; + type = SESSION_BUS; + return true; } +#define STR_SIZE(x) (x), sizeof(x)-1 + static constexpr boost::string_ref KDBUS_PATH_PREFIX{STR_SIZE("/sys/fs/kdbus/")}; + static constexpr boost::string_ref KDBUS_SYSTEM_BUS_PATH{STR_SIZE("/sys/fs/kdbus/0-system/bus")}; +#undef STR_SIZE - return resolved_path; -} +public: + BusPathResolver(const char *bus_path) + : resolved_path(realpath(bus_path, nullptr), [](const char *a) { free(const_cast(a)); }) + { + if (!resolved_path) + return; + + // recognize bus type + if (KDBUS_SYSTEM_BUS_PATH == resolved_path.get()) { + type = SYSTEM_BUS; + ok = true; + } else if (boost::string_ref(resolved_path.get()).starts_with(KDBUS_PATH_PREFIX)) { + ok = extract_bus_owner(); + } + } + operator bool() { return ok; } + const char *path() { return resolved_path.get(); } + BusType bus_type() { return type; } + uid_t bus_owner() { return owner; } +}; DBUSPOLICY1_EXPORT void* dbuspolicy1_init_shared(const char *bus_path, int fd) { - BusType bus_type = SESSION_BUS; - uid_t bus_owner = 0; + assert(bus_path); - auto resolved_path = bus_path_resolve(bus_path, bus_type, bus_owner); - if (nullptr == resolved_path) { + BusPathResolver path_resolver(bus_path); + if (!path_resolver) { LOGE("Error resolving bus path: %s", bus_path); return nullptr; } g_udesc.init(); + auto bus_type = path_resolver.bus_type(); + kconn *result = nullptr; - if (Checker::get(bus_type).can_open_owned_by(bus_owner)) { + if (Checker::get(bus_type).can_open_owned_by(path_resolver.bus_owner())) { if (-1 == fd) { - result = &kconn::get(bus_type, resolved_path.get()); + result = &kconn::get(bus_type, path_resolver.path()); } else { result = kconn::get_shared(bus_type, fd); } -- 2.7.4 From 9384276e586409f2910e3132a8ba9af93c56d2ab Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Wed, 10 Apr 2019 16:04:52 +0200 Subject: [PATCH 08/16] refactoring: group helper functions into a namespace This groups helper functions into an anonymous namespace. Change-Id: I1bf32e719f4268886014757a1423ef2c24b4c242 --- src/libdbuspolicy1.cpp | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/libdbuspolicy1.cpp b/src/libdbuspolicy1.cpp index 394e685..222ed9a 100644 --- a/src/libdbuspolicy1.cpp +++ b/src/libdbuspolicy1.cpp @@ -302,20 +302,9 @@ DBUSPOLICY1_EXPORT void* dbuspolicy1_init(const char *bus_path) return dbuspolicy1_init_shared(bus_path, -1); } -inline kconn *KCONN(void *config) { return static_cast(config); } -inline KdbusConnection &KDBUS_CONN(void *config) { return KCONN(config)->conn; } - -DBUSPOLICY1_EXPORT void dbuspolicy1_init_set_pool(void *configuration, void *pool) -{ - KDBUS_CONN(configuration).shared_init_pool(pool); -} - -DBUSPOLICY1_EXPORT void dbuspolicy1_free(void* configuration) -{ - auto kconn = KCONN(configuration); - if (kconn->can_be_freed) - delete kconn; -} +// helper functions +namespace { +constexpr kconn *KCONN(void *config) { return static_cast(config); } /* * This function prepares contents of info.names() for initialization of MatchItems. @@ -323,7 +312,7 @@ DBUSPOLICY1_EXPORT void dbuspolicy1_free(void* configuration) * If it fails, names are added from the 'name' parameter, which is treaten * as a string containing names separated by single space. */ -static int prepareNames(const char *name, KdbusConnectionInfo &info, +inline int prepareNames(const char *name, KdbusConnectionInfo &info, KdbusConnection::conn_info_type info_type) { if (name && *name) { int r = info.get(name, info_type); @@ -336,13 +325,26 @@ static int prepareNames(const char *name, KdbusConnectionInfo &info, return 0; } -static inline int decisionToRetCode(DecisionResult decision) { +constexpr int decisionToRetCode(DecisionResult decision) { return static_cast(decision); } -static inline ldp_xml_parser::MessageType toMessageType(int type) { +constexpr ldp_xml_parser::MessageType toMessageType(int type) { return static_cast(type); } +} // namespace + +DBUSPOLICY1_EXPORT void dbuspolicy1_init_set_pool(void *configuration, void *pool) +{ + KCONN(configuration)->conn.shared_init_pool(pool); +} + +DBUSPOLICY1_EXPORT void dbuspolicy1_free(void* configuration) +{ + auto kconn = KCONN(configuration); + if (kconn->can_be_freed) + delete kconn; +} DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration, const char *destination, -- 2.7.4 From 5d2b87a4218d64a6a5c528de9ef86166ee02f428 Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Mon, 15 Apr 2019 13:47:37 +0200 Subject: [PATCH 09/16] serializer: add option for checking for updates Developers may need to check if they already updated their serialized policy file. This adds -j option which does not write anything to the output file, but rather just checks if the generated file would have the same contents as an existing output file. Change-Id: I28ab3e992416d25c04206279275f007c0ca08919 --- src/dbuspolicy_serializer.cpp | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/src/dbuspolicy_serializer.cpp b/src/dbuspolicy_serializer.cpp index 7ca1c41..a575c6c 100644 --- a/src/dbuspolicy_serializer.cpp +++ b/src/dbuspolicy_serializer.cpp @@ -1,8 +1,10 @@ #include #include +#include #include #include +#include #include "internal/serializer.hpp" #include "internal/naive_policy_checker.hpp" #include "dbuspolicy1/libdbuspolicy1.h" @@ -17,23 +19,46 @@ static const struct option options[] = { static void print_help(const char *name) { cout << endl; - cout << "usage: " << name << " [-o output_filename] " << endl; - cout << " " << name << " {--system|--session} [-o output_filename]" << endl; + cout << "usage: " << name << " [-j] [-o output_filename] " << endl; + cout << " " << name << " {--system|--session} [-j] [-o output_filename]" << endl; cout << endl; cout << "If not specified, output_filename is input_filename.serialized" << endl; + cout << " -j - don't write anything, just check if the output file is valid and up to date" << endl; cout << endl; } +static int check(const char *input_filename, const std::string &output_filename) { + bool ok = false; + + cout << "Read from: " << input_filename << ", checking " << output_filename << "..." << endl; + ldp_xml_parser::Serializer serializer; + ostringstream output; + serializer.serialize(input_filename, output); + + ifstream serialized(output_filename, ifstream::binary|ifstream::ate); + + if (serialized && output.tellp() == serialized.tellg()) { + serialized.seekg(0, ifstream::beg); + + ok = equal(istreambuf_iterator(serialized), + istreambuf_iterator(), + output.str().begin()); + } + cout << output_filename << " is " << (ok ? "valid and up to date" : "not updated or invalid") << endl; + return ok ? 0 : 1; +} + int main(int argc, char *argv[]) { bool need_input_filename = true; + bool just_check = false; std::string output_filename; const char *input_filename = system_bus_conf_file_primary(); int c; while (1) { int option_index; - c = getopt_long(argc, argv, "o:", options, &option_index); + c = getopt_long(argc, argv, "o:j", options, &option_index); if (c == -1) break; @@ -46,6 +71,9 @@ int main(int argc, char *argv[]) case 'o': output_filename = optarg; break; + case 'j': + just_check = true; + break; } } @@ -61,6 +89,9 @@ int main(int argc, char *argv[]) if (output_filename.empty()) output_filename = std::string(input_filename) + ".serialized"; + if (just_check) + return check(input_filename, output_filename); + cout << "Read from: " << input_filename << " write to: " << output_filename << endl; ldp_xml_parser::Serializer serializer; ofstream output(output_filename, ofstream::binary); -- 2.7.4 From 6ab233eaee2b90a2b96aa8f42cade6f572d6b8be Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Thu, 18 Apr 2019 15:57:49 +0900 Subject: [PATCH 10/16] tslog: modified to support log level Change-Id: I9f5a4b9cae82737db6037ce56cf7b75bf8e8af0a Signed-off-by: sanghyeok.oh --- src/dbuspolicy_serializer.cpp | 2 ++ src/internal/serializer.cpp | 2 +- src/internal/tslog.cpp | 29 ++++++++++++++++++++--------- src/internal/tslog.hpp | 31 ++++++++++++++++++++++--------- 4 files changed, 45 insertions(+), 19 deletions(-) diff --git a/src/dbuspolicy_serializer.cpp b/src/dbuspolicy_serializer.cpp index 7ca1c41..a08c6a1 100644 --- a/src/dbuspolicy_serializer.cpp +++ b/src/dbuspolicy_serializer.cpp @@ -67,5 +67,7 @@ int main(int argc, char *argv[]) serializer.serialize(input_filename, output); + cout << "Write " << output.tellp() << " bytes" << endl; + return 0; } diff --git a/src/internal/serializer.cpp b/src/internal/serializer.cpp index 578157a..ac6841a 100644 --- a/src/internal/serializer.cpp +++ b/src/internal/serializer.cpp @@ -115,7 +115,7 @@ uint8_t* Serializer::serialize(const ldp_xml::StorageBackendXML &db, size_t &siz } uint8_t* Serializer::serialize(const std::string config_path, size_t &size) { - tslog::init(); + tslog::init(tslog::ldp_log_level::DEFAULT); ldp_xml::StorageBackendXML xmlStorage; if (!xmlStorage.init(config_path.c_str())) { diff --git a/src/internal/tslog.cpp b/src/internal/tslog.cpp index aa5a5f9..06ba0c0 100644 --- a/src/internal/tslog.cpp +++ b/src/internal/tslog.cpp @@ -23,7 +23,7 @@ namespace tslog { -int8_t g_verbosity{-1}; +ldp_log_level g_verbosity{ldp_log_level::SILENT}; pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; bool get_log_env(char const *name) { @@ -31,15 +31,14 @@ bool get_log_env(char const *name) { return ldp_log_mode && '0' != *ldp_log_mode; } -void init() { - g_verbosity = get_log_env("LDP_LOG") ? get_log_env("LDP_VERBOSE") : -1; +void init(ldp_log_level level) { + g_verbosity = get_log_env("LDP_LOG") ? (get_log_env("LDP_VERBOSE") ? ldp_log_level::DEBUG : ldp_log_level::VERBOSE): level; } -bool enabled() { return g_verbosity >= 0; } -bool verbose() { return g_verbosity > 0; } +bool enabled(ldp_log_level level) { return level <= g_verbosity; } -void flush() { - if (tslog::enabled()) { +void flush(ldp_log_level level) { + if (tslog::enabled(level)) { pthread_mutex_lock(&g_mutex); std::cout << std::flush; pthread_mutex_unlock(&g_mutex); @@ -58,13 +57,25 @@ void logWarning(const std::string &warning) LOGW("%s", warning.c_str()); } +void logDebug(const std::string &debug) +{ + log(debug, "\n"); + LOGD("%s", debug.c_str()); +} + +void logVerbose(const std::string &verbose) +{ + log_verbose(verbose, "\n"); + LOGD("%s", verbose.c_str()); +} + std::ostream &operator<<(std::ostream &stream, const print_errno &p) { char buf[256]; return stream << strerror_r(p.err, buf, sizeof(buf)); } -LogLock::LogLock() { - locked = tslog::enabled(); +LogLock::LogLock(ldp_log_level level) { + locked = tslog::enabled(level); if (locked) pthread_mutex_lock(&g_mutex); } diff --git a/src/internal/tslog.hpp b/src/internal/tslog.hpp index bcf6cf6..f2b4f59 100644 --- a/src/internal/tslog.hpp +++ b/src/internal/tslog.hpp @@ -29,22 +29,29 @@ namespace tslog { + enum class ldp_log_level { + SILENT, + ERROR, + WARNING, + DEFAULT = WARNING, + DEBUG, + VERBOSE + }; /** Checks value of environmental variable with given name */ bool get_log_env(char const *name); /** Checks environmental variables and sets global variable defining if logs are enabled */ - void init(); + void init(ldp_log_level level = ldp_log_level::SILENT); /** Checks if logs are enabled */ - bool enabled(); - - /** Checks if verbosity is enabled */ - bool verbose(); + bool enabled(ldp_log_level level = ldp_log_level::DEBUG); - void flush(); + void flush(ldp_log_level level = ldp_log_level::ERROR); void logError(const std::string &error); void logWarning(const std::string &warning); + void logDebug(const std::string &debug); + void logVerbose(const std::string &verbose); template void log_to_stream(std::ostream &stream, const Args &...args) { @@ -52,10 +59,16 @@ namespace tslog } template - void log(const Args &...args) { if (enabled()) log_to_stream(std::cout, args...); } + void log(const Args &...args) { if (enabled(ldp_log_level::DEBUG)) log_to_stream(std::cout, args...); } + + template + void log_error(const Args &...args) { if (enabled(ldp_log_level::ERROR)) log_to_stream(std::cout, args...); } + + template + void log_warning(const Args &...args) { if (enabled(ldp_log_level::WARNING)) log_to_stream(std::cout, args...); } template - void log_verbose(const Args &...args) { if (verbose()) log_to_stream(std::cout, args...); } + void log_verbose(const Args &...args) { if (enabled(ldp_log_level::VERBOSE)) log_to_stream(std::cout, args...); } struct print_errno { int err; @@ -70,7 +83,7 @@ namespace tslog class LogLock { bool locked; public: - LogLock(); + LogLock(ldp_log_level level = ldp_log_level::ERROR); ~LogLock(); }; } -- 2.7.4 From 244f5de93725b8520f2550663a85cfb1b2022861 Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Thu, 18 Apr 2019 15:58:35 +0900 Subject: [PATCH 11/16] tslog: change name log to log_debug Change-Id: Ib362f0cd385298a20443f90f9d4b78bcad84a8cc Signed-off-by: sanghyeok.oh --- src/internal/groups_proxy.cpp | 6 +++--- src/internal/storage_backend_serialized.cpp | 10 +++++----- src/internal/storage_backend_xml.cpp | 2 +- src/internal/tslog.cpp | 6 +++--- src/internal/tslog.hpp | 2 +- src/internal/xml_parser.cpp | 6 +++--- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/internal/groups_proxy.cpp b/src/internal/groups_proxy.cpp index d3e4e55..1ed0453 100644 --- a/src/internal/groups_proxy.cpp +++ b/src/internal/groups_proxy.cpp @@ -30,11 +30,11 @@ std::vector get_groups(const uid_t uid, const gid_t gid) { struct passwd pwd; if (getpwuid_r(uid, &pwd, buf.data(), buf.size(), &user_pw)) { - tslog::log("getpwuid_r failed uid:", uid, " gid: ", gid, "\n"); + tslog::log_error("getpwuid_r failed uid:", uid, " gid: ", gid, "\n"); return {}; } if (!user_pw) { - tslog::log("getpwuid_r failed. no matching password record was found uid:", uid, " gid: ", gid, "\n"); + tslog::log_error("getpwuid_r failed. no matching password record was found uid:", uid, " gid: ", gid, "\n"); return {}; } @@ -49,7 +49,7 @@ std::vector get_groups(const uid_t uid, const gid_t gid) { auto groups = std::vector (ngroups); int r = getgrouplist(user_pw->pw_name, gid, groups.data(), &ngroups); if (r < 0) { - tslog::log("getgrouplist failed uid:", uid, " gid: ", gid, "\n"); + tslog::log_error("getgrouplist failed uid:", uid, " gid: ", gid, "\n"); groups.clear(); } return groups; diff --git a/src/internal/storage_backend_serialized.cpp b/src/internal/storage_backend_serialized.cpp index b6b7409..f5c03e1 100644 --- a/src/internal/storage_backend_serialized.cpp +++ b/src/internal/storage_backend_serialized.cpp @@ -67,7 +67,7 @@ void StorageBackendSerialized::StorageBackendSerializedImpl::releaseMMap() { assert(0 != length); if (munmap(mem, length) != 0) - tslog::log("munmap(): ", tslog::print_errno(errno), "\n"); + tslog::log_error("munmap(): ", tslog::print_errno(errno), "\n"); mem = static_cast(MAP_FAILED); length = 0; @@ -77,7 +77,7 @@ void StorageBackendSerialized::StorageBackendSerializedImpl::releaseFD() { assert(-1 != fd); if (close(fd) != 0) - tslog::log("close(): ", tslog::print_errno(errno), "\n"); + tslog::log_error("close(): ", tslog::print_errno(errno), "\n"); fd = -1; } @@ -99,7 +99,7 @@ bool StorageBackendSerialized::StorageBackendSerializedImpl::init(const char *fi assert(nullptr == file); auto err = [filename] (const char *what) { - tslog::log("Can't ", what, " ", filename, ": ", tslog::print_errno(errno), "\n"); + tslog::log_error("Can't ", what, " ", filename, ": ", tslog::print_errno(errno), "\n"); return false; }; @@ -116,7 +116,7 @@ bool StorageBackendSerialized::StorageBackendSerializedImpl::init(const char *fi length = buf.st_size; if (length > MAX_SFILE_SIZE) { - tslog::log("Serialized file size(", length, ") is too large. (>", MAX_SFILE_SIZE, ") bytes.\n"); + tslog::log_error("Serialized file size(", length, ") is too large. (>", MAX_SFILE_SIZE, ") bytes.\n"); return false; } @@ -129,7 +129,7 @@ bool StorageBackendSerialized::StorageBackendSerializedImpl::init(const char *fi if (verify) { auto verifier = flatbuffers::Verifier(mem, length); if (!FB::VerifyFileBuffer(verifier)) { - tslog::log("verification of serialized data: failed\n"); + tslog::log_error("verification of serialized data: failed\n"); return false; } } diff --git a/src/internal/storage_backend_xml.cpp b/src/internal/storage_backend_xml.cpp index 95ee1b6..ec1b494 100644 --- a/src/internal/storage_backend_xml.cpp +++ b/src/internal/storage_backend_xml.cpp @@ -138,7 +138,7 @@ template void StorageBackendXML::addItem(const ldp_xml_parser::PolicyType policy_type, const ldp_xml_parser::PolicyTypeValue policy_type_value, T &item) { - tslog::log("Add item: ", item, ", decision: ", item.getDecision(), "\n"); + tslog::log_debug("Add item: ", item, ", decision: ", item.getDecision(), "\n"); pimpl->getPolicySetFromMatchItem().addItem(policy_type, policy_type_value, item); } diff --git a/src/internal/tslog.cpp b/src/internal/tslog.cpp index 06ba0c0..28a9808 100644 --- a/src/internal/tslog.cpp +++ b/src/internal/tslog.cpp @@ -47,19 +47,19 @@ void flush(ldp_log_level level) { void logError(const std::string &error) { - log(error, "\n"); + log_error(error, "\n"); LOGE("%s", error.c_str()); } void logWarning(const std::string &warning) { - log(warning, "\n"); + log_warning(warning, "\n"); LOGW("%s", warning.c_str()); } void logDebug(const std::string &debug) { - log(debug, "\n"); + log_debug(debug, "\n"); LOGD("%s", debug.c_str()); } diff --git a/src/internal/tslog.hpp b/src/internal/tslog.hpp index f2b4f59..f04fd16 100644 --- a/src/internal/tslog.hpp +++ b/src/internal/tslog.hpp @@ -59,7 +59,7 @@ namespace tslog } template - void log(const Args &...args) { if (enabled(ldp_log_level::DEBUG)) log_to_stream(std::cout, args...); } + void log_debug(const Args &...args) { if (enabled(ldp_log_level::DEBUG)) log_to_stream(std::cout, args...); } template void log_error(const Args &...args) { if (enabled(ldp_log_level::ERROR)) log_to_stream(std::cout, args...); } diff --git a/src/internal/xml_parser.cpp b/src/internal/xml_parser.cpp index 984dd53..77d0619 100644 --- a/src/internal/xml_parser.cpp +++ b/src/internal/xml_parser.cpp @@ -186,7 +186,7 @@ void XmlParser::elementEnd(const char *el) { } int XmlParser::parsePolicyConfigFile() { - tslog::log("XmlParser::parsePolicyConfigFile called with filename: ", main_filename, "\n"); + tslog::log_debug("XmlParser::parsePolicyConfigFile called with filename: ", main_filename); parsePolicyConfigFileInternal(main_filename); return ret_code; } @@ -250,7 +250,7 @@ std::unique_ptr file2str(const char *filename) { void XmlParser::parseXmlFile(const char *filename) { included_files.clear(); - tslog::log("Processing: ", filename, " ...\n"); + tslog::log_debug("Processing: ", filename, " ...\n"); tslog::log_verbose("=== XML PARSING BEGIN === : ", filename, '\n'); curr_dir = getDir(filename); @@ -297,7 +297,7 @@ void XmlParser::getIncludedFiles(const std::string& parent_dir, const std::strin std::cout << '\n'; } } else { - tslog::log("could not open directory ", dname, '\n'); + tslog::log_error("could not open directory ", dname, '\n'); } } -- 2.7.4 From 5e7e166f164accf34025f5f702b4f9908ee9c29d Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Thu, 18 Apr 2019 15:59:07 +0900 Subject: [PATCH 12/16] xml_parser: modified log to print out filename Change-Id: I63510b0b15e21aa8d583b98cb29b18d08bada5ab Signed-off-by: sanghyeok.oh --- src/internal/xml_parser.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/internal/xml_parser.cpp b/src/internal/xml_parser.cpp index 77d0619..faa2dfe 100644 --- a/src/internal/xml_parser.cpp +++ b/src/internal/xml_parser.cpp @@ -196,14 +196,14 @@ void XmlParser::parsePolicyConfigFileInternal(const char *filename) { try { parseXmlFile(filename); } catch (const std::runtime_error& ex) { - tslog::logError(std::string("Error parsing xml: Exception occured: ").append(ex.what()).c_str()); + tslog::logError(std::string(filename).append(": Error parsing xml: Exception occured: ").append(ex.what()).c_str()); if (isMainConfFile(filename)) { tslog::logError("Exiting parsing"); ret_code = -1; return; } } catch (...) { - tslog::logError("Error parsing xml: Exception occured: "); + tslog::logError(std::string(filename).append(" :Error parsing xml: Exception occured: ")); if (isMainConfFile(filename)) { tslog::logError("Exiting parsing"); ret_code = -1; -- 2.7.4 From 2a8585c01cb6285966dc5511bf403e9660f569c7 Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Thu, 18 Apr 2019 15:59:45 +0900 Subject: [PATCH 13/16] serialization: printer: change log level from silent to default Change-Id: I294e9b3f202002922ed266504ab99ff048ddb94c Signed-off-by: sanghyeok.oh --- src/dbuspolicy_printer.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dbuspolicy_printer.cpp b/src/dbuspolicy_printer.cpp index e64101b..18ed6ce 100644 --- a/src/dbuspolicy_printer.cpp +++ b/src/dbuspolicy_printer.cpp @@ -17,9 +17,11 @@ int main(int argc, const char **argv) { return 1; } + tslog::init(tslog::ldp_log_level::DEFAULT); + ldp_serialized::StorageBackendSerialized storage; - if (!storage.init(argv[1]), true) + if (!storage.init(argv[1], true)) return 1; storage.printContent(); -- 2.7.4 From f4dc600a226b1ee9105f6de4bf662c21a11dd605 Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Thu, 18 Apr 2019 16:00:22 +0900 Subject: [PATCH 14/16] serialization: make input consistency between printer and serializer Change-Id: I7ef136fde2a3b7cdd3cf117ccdc32fc5e0dce52c Signed-off-by: sanghyeok.oh --- src/dbuspolicy_printer.cpp | 47 ++++++++++++++++++++++++++++++++++++++++--- src/dbuspolicy_serializer.cpp | 3 ++- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/src/dbuspolicy_printer.cpp b/src/dbuspolicy_printer.cpp index 18ed6ce..8b5f2c8 100644 --- a/src/dbuspolicy_printer.cpp +++ b/src/dbuspolicy_printer.cpp @@ -1,27 +1,68 @@ #include "internal/print_content.hpp" #include "internal/storage_backend_serialized.hpp" #include +#include +#include "libdbuspolicy1-private.h" using namespace std; +static const struct option options[] = { + {"system", no_argument, 0, 0 }, + {"session", no_argument, 0, 0}, + {0, 0, 0, 0} +}; + static void print_help(const char *name) { cout << endl; - cout << "usage: " << name << " " << endl; + cout << "usage: " << name << " [-i input_filename]" << endl; + cout << " " << name << " {--system|--session}" << endl; cout << endl; } -int main(int argc, const char **argv) { +int main(int argc, char *argv[]) { + std::string input_filename; + int c; if (argc < 2) { print_help(argv[0]); return 1; } + while (1) { + int option_index; + c = getopt_long(argc, argv, "i:", options, &option_index); + if (c == -1) + break; + + switch(c) { + case 0: + if (option_index == 0) + input_filename = system_bus_conf_file_primary(); + else + input_filename = session_bus_conf_file_primary(); + input_filename.append(".serialized"); + break; + case 'i': + input_filename = optarg; + break; + case '?': + break; + } + if (!input_filename.empty()) + break; + } + + if (input_filename.empty()) { + cout << "No input filename" << endl; + print_help(argv[0]); + return 1; + } + tslog::init(tslog::ldp_log_level::DEFAULT); ldp_serialized::StorageBackendSerialized storage; - if (!storage.init(argv[1], true)) + if (!storage.init(input_filename.c_str(), true)) return 1; storage.printContent(); diff --git a/src/dbuspolicy_serializer.cpp b/src/dbuspolicy_serializer.cpp index a08c6a1..90a4f55 100644 --- a/src/dbuspolicy_serializer.cpp +++ b/src/dbuspolicy_serializer.cpp @@ -12,7 +12,8 @@ using namespace std; static const struct option options[] = { {"system", no_argument, 0, 0 }, - {"session", no_argument, 0, 0} + {"session", no_argument, 0, 0}, + {0, 0, 0, 0} }; static void print_help(const char *name) { -- 2.7.4 From ec779167655d76662ac6461f28a4c9fc7b628901 Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Tue, 30 Apr 2019 16:50:05 +0900 Subject: [PATCH 15/16] serialization: change tool name For readability and easy typing dbuspolicyserializer > dbuspolicy-serializer dbuspolicyprinter > dbuspolicy-printer Change-Id: I3a416805d66f31c16465a3a2854ceda15d783e9f Signed-off-by: sanghyeok.oh --- Makefile.am | 24 ++++++++++++------------ packaging/libdbuspolicy.spec | 6 +++--- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Makefile.am b/Makefile.am index c544561..f568ad8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -79,40 +79,40 @@ src_libdbuspolicy1_la_LDFLAGS = $(AM_LDFLAGS) \ -Wl,--version-script=$(top_srcdir)/src/libdbuspolicy1.sym EXTRA_src_libdbuspolicy1_la_DEPENDENCIES = ${top_srcdir}/src/libdbuspolicy1.sym -dbuspolicyserializer_SOURCES =\ +dbuspolicy_serializer_SOURCES =\ src/dbuspolicy_serializer.cpp -dbuspolicyserializer_CFLAGS="-Isrc/internal/include $(AM_CFLAGS)" +dbuspolicy_serializer_CFLAGS="-Isrc/internal/include $(AM_CFLAGS)" -# dbuspolicyserializer_LDFLAGS = $(AM_LDFLAGS) \ +# dbuspolicy_serializer_LDFLAGS = $(AM_LDFLAGS) \ # -version-info $(LIBDBUSPOLICY1_CURRENT):$(LIBDBUSPOLICY1_REVISION):$(LIBDBUSPOLICY1_AGE) \ # $(CYNARA_LIBS) \ # $(DLOG_LIBS) \ # -Wl,--version-script=$(top_srcdir)/src/libdbuspolicy1.sym -dbuspolicyserializer_LDADD = src/libinternal.a \ +dbuspolicy_serializer_LDADD = src/libinternal.a \ $(CYNARA_LIBS) \ $(DLOG_LIBS) \ -lexpat -EXTRA_dbuspolicyserializer_DEPENDENCIES = ${top_srcdir}/src/libdbuspolicy1.sym +EXTRA_dbuspolicy_serializer_DEPENDENCIES = ${top_srcdir}/src/libdbuspolicy1.sym -dbuspolicyserializerdir = /bin/ +dbuspolicy_serializerdir = /bin/ -dbuspolicyprinter_SOURCES =\ +dbuspolicy_printer_SOURCES =\ src/dbuspolicy_printer.cpp -dbuspolicyprinter_CFLAGS="-Isrc/internal/include $(AM_CFLAGS)" +dbuspolicy_printer_CFLAGS="-Isrc/internal/include $(AM_CFLAGS)" -dbuspolicyprinter_LDADD = src/libinternal.a \ +dbuspolicy_printer_LDADD = src/libinternal.a \ $(CYNARA_LIBS) \ $(DLOG_LIBS) \ -lexpat -EXTRA_dbuspolicyprinter_DEPENDENCIES = ${top_srcdir}/src/libdbuspolicy1.sym +EXTRA_dbuspolicy_printer_DEPENDENCIES = ${top_srcdir}/src/libdbuspolicy1.sym -bin_PROGRAMS = dbuspolicyserializer dbuspolicyprinter -dbuspolicyprinterdir = /bin/ +bin_PROGRAMS = dbuspolicy-serializer dbuspolicy-printer +dbuspolicy_printerdir = /bin/ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = src/libdbuspolicy1.pc diff --git a/packaging/libdbuspolicy.spec b/packaging/libdbuspolicy.spec index 4f067b6..493a3bb 100644 --- a/packaging/libdbuspolicy.spec +++ b/packaging/libdbuspolicy.spec @@ -32,7 +32,7 @@ policy handling (with SMACK support). This package contains development files. %description serializer -dbuspolicyserializer is a tool to serialize dbus policy +dbuspolicy-serializer is a tool to serialize dbus policy %description tests This package contains contains integration tests for libdbuspolicy. @@ -113,8 +113,8 @@ libtool --mode=install install -m 0755 %{runnername} %{btestrunnerdir} %manifest %{name}.manifest %license LICENSE.APACHE2.0 %defattr(-,root,root) -%{_bindir}/dbuspolicyserializer -%{_bindir}/dbuspolicyprinter +%{_bindir}/dbuspolicy-serializer +%{_bindir}/dbuspolicy-printer %if 0%{?enable_doxygen:1} %files doc -- 2.7.4 From 60aed661110746922500a855194adfe4d66a9112 Mon Sep 17 00:00:00 2001 From: Karol Lewandowski Date: Wed, 24 Apr 2019 14:10:05 +0200 Subject: [PATCH 16/16] tizen: Add new package to perform data verification on boot emergency.target is started on verification failure. Change-Id: I5c67e624d76440f9667602930aecb5adff233ecc --- packaging/libdbuspolicy-verify-data.service | 15 ++++++++++++++ packaging/libdbuspolicy-verify-data.target | 5 +++++ packaging/libdbuspolicy.spec | 32 +++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 packaging/libdbuspolicy-verify-data.service create mode 100644 packaging/libdbuspolicy-verify-data.target diff --git a/packaging/libdbuspolicy-verify-data.service b/packaging/libdbuspolicy-verify-data.service new file mode 100644 index 0000000..f52f10a --- /dev/null +++ b/packaging/libdbuspolicy-verify-data.service @@ -0,0 +1,15 @@ +[Unit] +Description=Verify libdbuspolicy serialized data correctness +DefaultDependencies=no +OnFailure=emergency.target +OnFailureJobMode=replace-irreversibly + +[Service] +Type=oneshot +RemainAfterExit=true +StandardInput=null +StandardOutput=kmsg+console +StandardError=kmsg+console +ExecStart=/usr/bin/dbuspolicy-serializer -j --system +ExecStart=/usr/bin/dbuspolicy-serializer -j --session +ExecStartPost=/bin/systemctl isolate graphical.target diff --git a/packaging/libdbuspolicy-verify-data.target b/packaging/libdbuspolicy-verify-data.target new file mode 100644 index 0000000..ea64083 --- /dev/null +++ b/packaging/libdbuspolicy-verify-data.target @@ -0,0 +1,5 @@ +[Unit] +Description=Verify D-Bus policy mode +Requires=libdbuspolicy-verify-data.service +After=libdbuspolicy-verify-data.service +AllowIsolate=yes diff --git a/packaging/libdbuspolicy.spec b/packaging/libdbuspolicy.spec index 493a3bb..813c109 100644 --- a/packaging/libdbuspolicy.spec +++ b/packaging/libdbuspolicy.spec @@ -6,6 +6,8 @@ Version: 1.1.0 Release: 0 Source: %{name}-%{version}.tar.gz Source1001: %{name}.manifest +Source2001: libdbuspolicy-verify-data.target +Source2002: libdbuspolicy-verify-data.service BuildRequires: boost-devel BuildRequires: libexpat-devel BuildRequires: pkgconfig(cynara-client) @@ -18,6 +20,10 @@ Summary: Helper library for fine-grained userspace policy handling-develo %package serializer Summary: Tool to serialize dbus policy +%package assert-data-valid +Requires: %{name}-serializer +Summary: Systemd units to perform boot-time serialized data verification + %package tests Summary: Helper library for fine-grained userspace policy handling-development package Requires: %{name} = %{version} @@ -34,6 +40,11 @@ development files. %description serializer dbuspolicy-serializer is a tool to serialize dbus policy +%description assert-data-valid +Perform boot-time serialized data verification, fail the boot if vierification fails +. +Note that installing this package actually replaces systemd default.target. Use with care. + %description tests This package contains contains integration tests for libdbuspolicy. @@ -53,6 +64,8 @@ Doxygen documentation for libdbuspolicy. %prep %setup -q cp %{SOURCE1001} . +cp %{SOURCE2001} ./libdbuspolicy-verify-data.target +cp %{SOURCE2002} ./libdbuspolicy-verify-data.service %build %reconfigure --libdir=%{_libdir} --prefix=/usr --enable-tests \ @@ -92,9 +105,22 @@ libtool --mode=install install -m 0755 stest_* dbus_daemon %{btestsuitedir} mkdir -p %{btestrunnerdir} libtool --mode=install install -m 0755 %{runnername} %{btestrunnerdir} +mkdir -p -m755 %{buildroot}%{_unitdir} +install -m644 libdbuspolicy-verify-data.target %{buildroot}/%{_unitdir}/ +install -m644 libdbuspolicy-verify-data.service %{buildroot}/%{_unitdir}/ + %post -p /sbin/ldconfig %postun -p /sbin/ldconfig +%posttrans assert-data-valid +rm -f %{_unitdir}/.%{name}.backup.default.target +mv %{_unitdir}/default.target %{_unitdir}/.%{name}.backup.default.target +ln -sf libdbuspolicy-verify-data.target %{_unitdir}/default.target + +%preun assert-data-valid +rm -f %{_unitdir}/default.target +mv %{_unitdir}/.%{name}.backup.default.target %{_unitdir}/default.target + %files %manifest %{name}.manifest %license LICENSE.APACHE2.0 @@ -116,6 +142,12 @@ libtool --mode=install install -m 0755 %{runnername} %{btestrunnerdir} %{_bindir}/dbuspolicy-serializer %{_bindir}/dbuspolicy-printer +%files assert-data-valid +%manifest %{name}.manifest +%license LICENSE.APACHE2.0 +%{_unitdir}/libdbuspolicy-verify-data.target +%{_unitdir}/libdbuspolicy-verify-data.service + %if 0%{?enable_doxygen:1} %files doc %license LICENSE.APACHE2.0 -- 2.7.4