From: Tomasz Swierczek Date: Fri, 5 Jul 2019 05:21:11 +0000 (+0200) Subject: Optimize nss plugin memory usage X-Git-Tag: accepted/tizen/unified/20190725.042914~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F88%2F209388%2F12;p=platform%2Fcore%2Fsecurity%2Fsecurity-manager.git Optimize nss plugin memory usage Made the nss module not linked with commons or client library. Using security-manager client library in nss module caused additional memory usage by private data in each loaded libaries out of which most were not needed for nss (smack, pcap, procps, rt, sqlite, cynara-*, security-privilege-manager, mount, crypt, blkid, pkgmgr_parser, vconf, minizip, pcre, uuid, xml2, gio, z, buxton2, lzma, gmodule, resolv, ffi, tzplatformconfig, dlog). Linking with dlog & tzplatformconfig left only in debug mode. To test it, use "gdb id", break point on getgrgid, measure change of PSS after finishing the function execution with vs. without the patch. The PSS value of id process should go down by approx. 0.4 - 0.5 MB (depending on the system load & number of processes). Change-Id: If2cede89885320ea83ca79fd54770a7ea24d87d8 --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e794c6..d6c8416 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2011 - 2018 Samsung Electronics Co., Ltd All Rights Reserved +# Copyright (c) 2011 - 2019 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. @@ -73,18 +73,6 @@ ADD_DEFINITIONS("-DASKUSER_ENABLED") OPTION(DPL_WITH_DLOG "DPL DLOG backend" ON) OPTION(DPL_WITH_SYSTEMD_JOURNAL "DPL systemd-journal backend" OFF) -IF(DPL_WITH_DLOG) - ADD_DEFINITIONS("-DDPL_DLOG_ENABLED") -ENDIF(DPL_WITH_DLOG) - -IF(DPL_WITH_SYSTEMD_JOURNAL) - ADD_DEFINITIONS("-DDPL_SYSTEMD_JOURNAL_ENABLED") -ENDIF(DPL_WITH_SYSTEMD_JOURNAL) - -IF(DB_LOGS) - ADD_DEFINITIONS("-DDB_LOGS") -ENDIF(DB_LOGS) - ADD_DEFINITIONS("-DBUILD_TYPE_${CMAKE_BUILD_TYPE}") SET(INCLUDE_PATH ${PROJECT_SOURCE_DIR}/src/include) @@ -102,9 +90,9 @@ SET(TARGET_CLIENT "security-manager-client") SET(TARGET_COMMON "security-manager-commons") SET(TARGET_CMD "security-manager-cmd") SET(TARGET_CLEANUP "security-manager-cleanup") -SET(TARGET_NSS "security-manager-nss") SET(TARGET_LOADER "security-manager-rules-loader") SET(TARGET_TEST_LOADER "security-manager-test-rules-loader") +SET(TARGET_NSS "security-manager-nss") ADD_SUBDIRECTORY(src) ADD_SUBDIRECTORY(pc) @@ -112,3 +100,28 @@ ADD_SUBDIRECTORY(systemd) ADD_SUBDIRECTORY(db) ADD_SUBDIRECTORY(policy) ADD_SUBDIRECTORY(test) + +SET(LOG_TARGET_LIST ${TARGET_SERVER} + ${TARGET_CLIENT} + ${TARGET_COMMON} + ${TARGET_CMD} + ${TARGET_CLEANUP} + ${TARGET_LOADER} + ${TARGET_TEST_LOADER}) + +# NSS target doesn't get ANY logs by design in release mode +IF(CMAKE_BUILD_TYPE MATCHES "DEBUG") + LIST(APPEND ${LOG_TARGET_LIST} ${TARGET_NSS}) +ENDIF(CMAKE_BUILD_TYPE MATCHES "DEBUG") + +FOREACH(TARGET_NAME ${LOG_TARGET_LIST}) + IF(DPL_WITH_DLOG) + TARGET_COMPILE_DEFINITIONS(${TARGET_NAME} PRIVATE DPL_DLOG_ENABLED) + ENDIF(DPL_WITH_DLOG) + IF(DPL_WITH_SYSTEMD_JOURNAL) + TARGET_COMPILE_DEFINITIONS(${TARGET_NAME} PRIVATE DPL_SYSTEMD_JOURNAL_ENABLED) + ENDIF(DPL_WITH_SYSTEMD_JOURNAL) + IF(DB_LOGS) + TARGET_COMPILE_DEFINITIONS(${TARGET_NAME} PRIVATE DB_LOGS) + ENDIF(DB_LOGS) +ENDFOREACH(TARGET_NAME) diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index 8862ca0..d99027b 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -25,6 +25,7 @@ INCLUDE_DIRECTORIES( SET(CLIENT_SOURCES ${CLIENT_PATH}/client-security-manager.cpp + ${CLIENT_PATH}/client-security-manager-internal.cpp ${CLIENT_PATH}/client-common.cpp ${CLIENT_PATH}/client-offline.cpp ${CLIENT_PATH}/client-label-monitor.cpp diff --git a/src/client/client-common.cpp b/src/client/client-common.cpp index 16050f5..3ac353b 100644 --- a/src/client/client-common.cpp +++ b/src/client/client-common.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2000 - 2019 Samsung Electronics Co., Ltd All Rights Reserved * * Contact: Rafal Krypa * @@ -22,29 +22,9 @@ * @brief This file is implementation of client-common functions. */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include -#include #include -#include - -#include - namespace { void securityClientEnableLogSystem(void) { @@ -55,36 +35,6 @@ void securityClientEnableLogSystem(void) { } // namespace anonymous -namespace SecurityManager { - -int try_catch(const std::function& func) -{ - try { - return func(); - } catch (abi::__forced_unwind &) { - throw; - } catch (const Exception &e) { - LogError("SecurityManager::Exception " << e.DumpToString()); - std::cerr << "SecurityManager::Exception " << e.DumpToString() << std::endl; - } catch (const std::bad_alloc &e) { - LogError("Memory allocation failed: " << e.what()); - std::cerr << "Memory allocation failed: " << e.what() << std::endl; - return SECURITY_MANAGER_ERROR_MEMORY; - } catch (const std::system_error &e) { - LogError("STD system_error: " << e.code() << "-" << e.what()); - std::cerr << "STD system_error: " << e.code() << "-" << e.what() << std::endl; - } catch (const std::exception &e) { - LogError("STD exception " << e.what()); - std::cerr << "STD exception " << e.what() << std::endl; - } catch (...) { - LogError("Unknown exception occurred"); - std::cerr << "Unknown exception occurred" << std::endl; - } - return SECURITY_MANAGER_ERROR_UNKNOWN; -} - -} // namespace SecurityMANAGER - static void init_lib(void) __attribute__ ((constructor)); static void init_lib(void) { diff --git a/src/client/client-label-monitor.cpp b/src/client/client-label-monitor.cpp index 757be3a..10a5687 100644 --- a/src/client/client-label-monitor.cpp +++ b/src/client/client-label-monitor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2016 - 2019 Samsung Electronics Co., Ltd All Rights Reserved * * Contact: Rafal Krypa * @@ -40,7 +40,6 @@ #include #include -#include #include #include #include diff --git a/src/client/client-offline.cpp b/src/client/client-offline.cpp index b8f39e8..87420d0 100644 --- a/src/client/client-offline.cpp +++ b/src/client/client-offline.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2000 - 2019 Samsung Electronics Co., Ltd All Rights Reserved * * Contact: Rafal Krypa * @@ -22,7 +22,7 @@ * @brief Helper class for client "off-line" mode detection */ -#include +#include #include #include #include diff --git a/src/client/client-security-manager-internal.cpp b/src/client/client-security-manager-internal.cpp new file mode 100644 index 0000000..b0c807c --- /dev/null +++ b/src/client/client-security-manager-internal.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Tomasz Swierczek + * + * 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 + * + * Security Manager NSS library + */ +/* + * @file client-security-manager-internal.cpp + * @author Tomasz Swierczek + * @version 1.0 + * @brief This file contains implementation of SM APIs needed to be linked separately into NSS module + */ + +#include + +#include + +#include +#include +#include + +int security_manager_groups_get_internal(gid_t **groups, size_t *groups_count) +{ + using namespace SecurityManager; + if (!groups || !groups_count) + return SECURITY_MANAGER_ERROR_INPUT_PARAM; + return try_catch([&]() -> int { + std::vector vgroups; + loadGroups(vgroups); + return group_vector_to_array(vgroups, groups, groups_count); + }); +} + +int security_manager_groups_get_for_user_internal(uid_t uid, gid_t **groups, size_t *groups_count) +{ + using namespace SecurityManager; + if (!groups || !groups_count) + return SECURITY_MANAGER_ERROR_INPUT_PARAM; + + // Security manager does not manage platform system daemons + // This 5000 value is defined only in this document: + // https://wiki.tizen.org/wiki/Security/User_and_group_ID_assignment_policy + // TODO: Value 5000 should be defined in tizen-platform-config + + if (uid < 5000) { + return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT; + } + + return try_catch([&]() -> int { + ClientRequest request(SecurityModuleCall::GROUPS_FOR_UID); + if (request.send(uid).failed()) + return request.getStatus(); + + std::vector vgroups; + request.recv(vgroups); + + return group_vector_to_array(vgroups, groups, groups_count); + }); +} diff --git a/src/client/client-security-manager.cpp b/src/client/client-security-manager.cpp index 8c2a4f7..3419094 100644 --- a/src/client/client-security-manager.cpp +++ b/src/client/client-security-manager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2000 - 2019 Samsung Electronics Co., Ltd All Rights Reserved * * Contact: Rafal Krypa * @@ -54,8 +54,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -1307,95 +1307,16 @@ void security_manager_policy_levels_free(char **levels, size_t levels_count) delete[] levels; } -static void loadGroups(std::vector &vgroups) -{ - auto groupsMapData = ConfigFile(PRIVILEGE_GROUP_LIST_FILE).read(); - for (const auto &groupsMapEntry : groupsMapData) { - if (groupsMapEntry.size() != 2) - continue; - - const std::string &groupName = groupsMapEntry[1]; - std::vector buf(1024); - group *result = nullptr; - group grp; - - for (;;) { - int ret = TEMP_FAILURE_RETRY(getgrnam_r(groupName.c_str(), &grp, buf.data(), buf.size(), &result)); - if (ret == ERANGE) { - buf.resize(buf.size() * 2); - continue; - } - if (result == nullptr && ret == 0) - ret = ENOENT; - - if (ret != 0) { - LogError("Cannot map group " + groupName + " to gid"); - throw std::system_error(ret, std::system_category(), "getgrnam_r() failed"); - } - break; - } - vgroups.push_back(result->gr_gid); - } -} - -static int group_vector_to_array(const std::vector &vgroups, gid_t **groups, size_t *groups_count) -{ - if (vgroups.empty()) { - *groups_count = 0; - *groups = NULL; - return SECURITY_MANAGER_SUCCESS; - } - - size_t size = vgroups.size() * sizeof(gid_t); - *groups = static_cast(malloc(size)); - if (*groups == nullptr) - return SECURITY_MANAGER_ERROR_MEMORY; - - *groups_count = vgroups.size(); - memcpy(*groups, vgroups.data(), size); - - return SECURITY_MANAGER_SUCCESS; -} - SECURITY_MANAGER_API int security_manager_groups_get(gid_t **groups, size_t *groups_count) { - using namespace SecurityManager; - if (!groups || !groups_count) - return SECURITY_MANAGER_ERROR_INPUT_PARAM; - return try_catch([&]() -> int { - std::vector vgroups; - loadGroups(vgroups); - return group_vector_to_array(vgroups, groups, groups_count); - }); + return security_manager_groups_get_internal(groups, groups_count); } SECURITY_MANAGER_API int security_manager_groups_get_for_user(uid_t uid, gid_t **groups, size_t *groups_count) { - using namespace SecurityManager; - if (!groups || !groups_count) - return SECURITY_MANAGER_ERROR_INPUT_PARAM; - - // Security manager does not manage platform system daemons - // This 5000 value is defined only in this document: - // https://wiki.tizen.org/wiki/Security/User_and_group_ID_assignment_policy - // TODO: Value 5000 should be defined in tizen-platform-config - - if (uid < 5000) { - return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT; - } - - return try_catch([&]() -> int { - ClientRequest request(SecurityModuleCall::GROUPS_FOR_UID); - if (request.send(uid).failed()) - return request.getStatus(); - - std::vector vgroups; - request.recv(vgroups); - - return group_vector_to_array(vgroups, groups, groups_count); - }); + return security_manager_groups_get_for_user_internal(uid, groups, groups_count); } static lib_retcode get_app_and_pkg_id_from_smack_label( diff --git a/src/client/include/client-common.h b/src/client/include/client-common.h deleted file mode 100644 index e9ff18e..0000000 --- a/src/client/include/client-common.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved - * - * Contact: Rafal Krypa - * - * 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 - */ -/* - * @file client-common.h - * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) - * @version 1.0 - * @brief This file constains implementation of common types - * used in security manager. - */ - -#pragma once - -#include - -#define SECURITY_MANAGER_API __attribute__((visibility("default"))) - -namespace SecurityManager { - -/* - * Decorator function that performs frequently repeated exception handling in - * SS client API functions. Accepts lambda expression as an argument. - */ -int try_catch(const std::function& func); - -} // namespace SecurityManager diff --git a/src/client/include/client-security-manager-internal.h b/src/client/include/client-security-manager-internal.h new file mode 100644 index 0000000..e6c3578 --- /dev/null +++ b/src/client/include/client-security-manager-internal.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Tomasz Swierczek + * + * 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 + * + * Security Manager NSS library + */ +/* + * @file client-security-manager-internal.h + * @author Tomasz Swierczek + * @version 1.0 + * @brief This file contains declaration of SM APIs needed to be linked separately into NSS module + */ + +#pragma once + +#include + +int security_manager_groups_get_internal(gid_t **groups, size_t *groups_count); +int security_manager_groups_get_for_user_internal(uid_t uid, gid_t **groups, size_t *groups_count); diff --git a/src/cmd/security-manager-cmd.cpp b/src/cmd/security-manager-cmd.cpp index 89faebf..c200813 100644 --- a/src/cmd/security-manager-cmd.cpp +++ b/src/cmd/security-manager-cmd.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 - 2018 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2000 - 2019 Samsung Electronics Co., Ltd All Rights Reserved * * Contact: Rafal Krypa * @@ -39,6 +39,7 @@ #include #include +#include #include namespace po = boost::program_options; diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 6222ba6..2d1422a 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -49,11 +49,11 @@ SET(COMMON_SOURCES ${DPL_PATH}/db/src/naive_synchronization_object.cpp ${DPL_PATH}/db/src/sql_connection.cpp ${COMMON_PATH}/channel.cpp - ${COMMON_PATH}/config.cpp ${COMMON_PATH}/config-file.cpp ${COMMON_PATH}/connection.cpp ${COMMON_PATH}/credentials.cpp ${COMMON_PATH}/cynara.cpp + ${COMMON_PATH}/db-config.cpp ${COMMON_PATH}/filesystem.cpp ${COMMON_PATH}/file-lock.cpp ${COMMON_PATH}/permissible-set.cpp diff --git a/src/common/config.cpp b/src/common/db-config.cpp similarity index 75% rename from src/common/config.cpp rename to src/common/db-config.cpp index 17d3641..23ac592 100644 --- a/src/common/config.cpp +++ b/src/common/db-config.cpp @@ -1,7 +1,7 @@ /* - * Copyright (c) 2015 - 2018 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved * - * Contact: Rafal Krypa + * Contact: Tomasz Swierczek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,13 +16,14 @@ * limitations under the License */ /* - * @file config.cpp - * @author Zofia Abramowska + * @file db-config.cpp + * @author Tomasz Swierczek * @version 1.0 - * @brief Setting values of Configuration options + * @brief Configuration options for DB - implementation */ -#include +#include +#include namespace SecurityManager { diff --git a/src/common/include/config.h b/src/common/include/config.h index 230f15b..24e0eac 100644 --- a/src/common/include/config.h +++ b/src/common/include/config.h @@ -24,30 +24,6 @@ #pragma once -#include -#include - -namespace SecurityManager { - -namespace Config { - -std::string getPrivilegeDbPath(); -std::string getPrivilegeDbFallbackPath(); - -}; - -} /* namespace SecurityManager */ - -// If database initialization fails, restoration to a fallback snapshot is -// attempted. If the restoration succeeds, a file flag is created to notify -// other system components. -// For database placed in "$f" the filename is ("$f" DB_RECOVERED_SUFFIX). -#define DB_RECOVERED_SUFFIX "-recovered" -#define DB_JOURNAL_SUFFIX "-journal" - -#define DB_OK_MARKER "/tmp/.security-manager.db.ok" - - /* Service name */ #define SERVICE_NAME "security-manager" diff --git a/src/common/include/db-config.h b/src/common/include/db-config.h new file mode 100644 index 0000000..e4f0268 --- /dev/null +++ b/src/common/include/db-config.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Tomasz Swierczek + * + * 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 + */ +/* + * @file db-config.h + * @author Tomasz Swierczek + * @version 1.0 + * @brief Definition of configuration options for DB + */ + +#pragma once + +#include + +namespace SecurityManager { + +namespace Config { + +std::string getPrivilegeDbPath(); +std::string getPrivilegeDbFallbackPath(); + +}; + +} /* namespace SecurityManager */ + +// If database initialization fails, restoration to a fallback snapshot is +// attempted. If the restoration succeeds, a file flag is created to notify +// other system components. +// For database placed in "$f" the filename is ("$f" DB_RECOVERED_SUFFIX). +#define DB_RECOVERED_SUFFIX "-recovered" +#define DB_JOURNAL_SUFFIX "-journal" + +#define DB_OK_MARKER "/tmp/.security-manager.db.ok" diff --git a/src/common/include/privilege_db.h b/src/common/include/privilege_db.h index 8e20650..b84aa04 100644 --- a/src/common/include/privilege_db.h +++ b/src/common/include/privilege_db.h @@ -1,7 +1,7 @@ /* * security-manager, database access * - * Copyright (c) 2000 - 2018 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2000 - 2019 Samsung Electronics Co., Ltd All Rights Reserved * * Contact: Rafal Krypa * @@ -41,6 +41,7 @@ #include #include +#include #include #include #include "security-manager-types.h" diff --git a/src/common/include/utils.h b/src/common/include/utils.h index a1d0514..60e0200 100644 --- a/src/common/include/utils.h +++ b/src/common/include/utils.h @@ -36,8 +36,16 @@ #include +#define SECURITY_MANAGER_API __attribute__((visibility("default"))) + namespace SecurityManager { +/* + * Decorator function that performs frequently repeated exception handling in + * SS client API functions. Accepts lambda expression as an argument. + */ +int try_catch(const std::function& func); + time_t monotonicNow(); // Used for measuring function/method/scope execution time @@ -57,6 +65,10 @@ private: #define LOG_EXECUTION_TIME(location, creds) do {} while (0) #endif +// Group operations +void loadGroups(std::vector &vgroups); +int group_vector_to_array(const std::vector &vgroups, gid_t **groups, size_t *groups_count); + // Pointer template std::unique_ptr makeUnique(T *ptr) diff --git a/src/common/utils.cpp b/src/common/utils.cpp index fb215ed..32b06d6 100644 --- a/src/common/utils.cpp +++ b/src/common/utils.cpp @@ -22,13 +22,51 @@ * @brief Implementation of utility functions */ +#include +#include +#include +#include +#include +#include #include +#include +#include + #include #include +#include + +#include namespace SecurityManager { +int try_catch(const std::function& func) +{ + try { + return func(); + } catch (abi::__forced_unwind &) { + throw; + } catch (const Exception &e) { + LogError("SecurityManager::Exception " << e.DumpToString()); + std::cerr << "SecurityManager::Exception " << e.DumpToString() << std::endl; + } catch (const std::bad_alloc &e) { + LogError("Memory allocation failed: " << e.what()); + std::cerr << "Memory allocation failed: " << e.what() << std::endl; + return SECURITY_MANAGER_ERROR_MEMORY; + } catch (const std::system_error &e) { + LogError("STD system_error: " << e.code() << "-" << e.what()); + std::cerr << "STD system_error: " << e.code() << "-" << e.what() << std::endl; + } catch (const std::exception &e) { + LogError("STD exception " << e.what()); + std::cerr << "STD exception " << e.what() << std::endl; + } catch (...) { + LogError("Unknown exception occurred"); + std::cerr << "Unknown exception occurred" << std::endl; + } + return SECURITY_MANAGER_ERROR_UNKNOWN; +} + time_t monotonicNow() { struct timespec now; if (clock_gettime(CLOCK_MONOTONIC_RAW, &now) == -1) { @@ -65,4 +103,54 @@ ScopedTimeStamper::~ScopedTimeStamper() LogDebug("Execution of " << m_locationStr << " took " << sec << " seconds"); } +void loadGroups(std::vector &vgroups) +{ + auto groupsMapData = ConfigFile(PRIVILEGE_GROUP_LIST_FILE).read(); + for (const auto &groupsMapEntry : groupsMapData) { + if (groupsMapEntry.size() != 2) + continue; + + const std::string &groupName = groupsMapEntry[1]; + std::vector buf(1024); + group *result = nullptr; + group grp; + + for (;;) { + int ret = TEMP_FAILURE_RETRY(getgrnam_r(groupName.c_str(), &grp, buf.data(), buf.size(), &result)); + if (ret == ERANGE) { + buf.resize(buf.size() * 2); + continue; + } + if (result == nullptr && ret == 0) + ret = ENOENT; + + if (ret != 0) { + LogError("Cannot map group " + groupName + " to gid"); + throw std::system_error(ret, std::system_category(), "getgrnam_r() failed"); + } + break; + } + vgroups.push_back(result->gr_gid); + } +} + +int group_vector_to_array(const std::vector &vgroups, gid_t **groups, size_t *groups_count) +{ + if (vgroups.empty()) { + *groups_count = 0; + *groups = NULL; + return SECURITY_MANAGER_SUCCESS; + } + + size_t size = vgroups.size() * sizeof(gid_t); + *groups = static_cast(malloc(size)); + if (*groups == nullptr) + return SECURITY_MANAGER_ERROR_MEMORY; + + *groups_count = vgroups.size(); + memcpy(*groups, vgroups.data(), size); + + return SECURITY_MANAGER_SUCCESS; +} + } /* namespace SecurityManager */ diff --git a/src/nss/CMakeLists.txt b/src/nss/CMakeLists.txt index 446002d..29f8556 100644 --- a/src/nss/CMakeLists.txt +++ b/src/nss/CMakeLists.txt @@ -3,6 +3,10 @@ SET(NSS_PLUGIN_VERSION ${NSS_PLUGIN_VERSION_MAJOR}.0.0) SET(LIBRARY_FILE_NAME "nss_securitymanager") +IF(CMAKE_BUILD_TYPE MATCHES "DEBUG" AND DPL_WITH_DLOG) + PKG_CHECK_MODULES(NSS_DLOG_DEP REQUIRED dlog libtzplatform-config) +ENDIF(CMAKE_BUILD_TYPE MATCHES "DEBUG" AND DPL_WITH_DLOG) + INCLUDE_DIRECTORIES( ${INCLUDE_PATH} ${CLIENT_PATH}/include @@ -10,12 +14,37 @@ INCLUDE_DIRECTORIES( ${DPL_PATH}/core/include ${DPL_PATH}/log/include ${COMMON_PATH}/include + ${NSS_DLOG_DEP_INCLUDE_DIRS} ) SET(NSS_SOURCES ${NSS_PATH}/nss_securitymanager.cpp + ${DPL_PATH}/log/src/abstract_log_provider.cpp + ${DPL_PATH}/log/src/log.cpp + ${DPL_PATH}/log/src/old_style_log_provider.cpp + ${DPL_PATH}/core/src/assert.cpp + ${DPL_PATH}/core/src/binary_queue.cpp + ${DPL_PATH}/core/src/colors.cpp + ${DPL_PATH}/core/src/exception.cpp + ${DPL_PATH}/core/src/noncopyable.cpp + ${DPL_PATH}/core/src/serialization.cpp + ${DPL_PATH}/core/src/errno_string.cpp + ${COMMON_PATH}/channel.cpp + ${COMMON_PATH}/config-file.cpp + ${COMMON_PATH}/connection.cpp + ${COMMON_PATH}/filesystem.cpp + ${COMMON_PATH}/protocols.cpp + ${COMMON_PATH}/message-buffer.cpp + ${COMMON_PATH}/utils.cpp + ${CLIENT_PATH}/client-security-manager-internal.cpp ) +IF(CMAKE_BUILD_TYPE MATCHES "DEBUG" AND DPL_WITH_DLOG) + SET(NSS_SOURCES + ${NSS_SOURCES} + ${DPL_PATH}/log/src/dlog_log_provider.cpp) +ENDIF(CMAKE_BUILD_TYPE MATCHES "DEBUG" AND DPL_WITH_DLOG) + ADD_LIBRARY(${TARGET_NSS} SHARED ${NSS_SOURCES}) SET_TARGET_PROPERTIES(${TARGET_NSS} @@ -26,9 +55,6 @@ SET_TARGET_PROPERTIES(${TARGET_NSS} VERSION ${NSS_PLUGIN_VERSION} ) -TARGET_LINK_LIBRARIES(${TARGET_NSS} - ${TARGET_CLIENT} - ${TARGET_COMMON} - ) +TARGET_LINK_LIBRARIES(${TARGET_NSS} ${NSS_DLOG_DEP_LIBRARIES} "-z defs") INSTALL(TARGETS ${TARGET_NSS} LIBRARY DESTINATION ${LIB_INSTALL_DIR} NAMELINK_SKIP) diff --git a/src/nss/nss_securitymanager.cpp b/src/nss/nss_securitymanager.cpp index 4c7eef3..873622d 100644 --- a/src/nss/nss_securitymanager.cpp +++ b/src/nss/nss_securitymanager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2016 - 2019 Samsung Electronics Co., Ltd All Rights Reserved * * Contact: Rafal Krypa * @@ -29,13 +29,16 @@ #include #include #include +#include #include #include - #include #include -#include +#include +#include +#include +#include #include namespace { @@ -87,6 +90,9 @@ enum nss_status _nss_securitymanager_initgroups_dyn(const char *user, gid_t grou std::vector buffer(BUFFER_SIZE); passwd pwnambuffer; passwd *pwnam = NULL; + auto& logSystem = SecurityManager::Singleton::Instance(); + + logSystem.SetTag("SECURITY_MANAGER_NSS"); while (ERANGE == (ret = TEMP_FAILURE_RETRY(getpwnam_r(user, &pwnambuffer, buffer.data(), buffer.size(), &pwnam))) && buffer.size() < MEMORY_LIMIT) @@ -106,11 +112,11 @@ enum nss_status _nss_securitymanager_initgroups_dyn(const char *user, gid_t grou gid_t *groups = NULL; size_t groupsCount; - ret = security_manager_groups_get_for_user(pwnam->pw_uid, &groups, &groupsCount); + ret = security_manager_groups_get_for_user_internal(pwnam->pw_uid, &groups, &groupsCount); if (ret == SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT) { // If user is not managed by Security Manager, we want to apply all the groups - ret = security_manager_groups_get(&groups, &groupsCount); + ret = security_manager_groups_get_internal(&groups, &groupsCount); } if (ret == SECURITY_MANAGER_ERROR_MEMORY) { diff --git a/src/server/rules-loader/security-manager-rules-loader.cpp b/src/server/rules-loader/security-manager-rules-loader.cpp index 748f186..45d32c1 100644 --- a/src/server/rules-loader/security-manager-rules-loader.cpp +++ b/src/server/rules-loader/security-manager-rules-loader.cpp @@ -33,6 +33,7 @@ #include #include +#include #include #include diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4efb856..888162f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -72,8 +72,8 @@ SET(SM_TESTS_SOURCES ${DPL_PATH}/log/src/abstract_log_provider.cpp ${DPL_PATH}/log/src/log.cpp ${DPL_PATH}/log/src/old_style_log_provider.cpp - ${PROJECT_SOURCE_DIR}/src/common/config.cpp ${PROJECT_SOURCE_DIR}/src/common/config-file.cpp + ${PROJECT_SOURCE_DIR}/src/common/db-config.cpp ${PROJECT_SOURCE_DIR}/src/common/file-lock.cpp ${PROJECT_SOURCE_DIR}/src/common/privilege_db.cpp ${PROJECT_SOURCE_DIR}/src/common/smack-check.cpp @@ -100,7 +100,7 @@ SET(SM_PERFORMANCE_TESTS_SOURCES ${DPL_PATH}/log/src/abstract_log_provider.cpp ${DPL_PATH}/log/src/log.cpp ${DPL_PATH}/log/src/old_style_log_provider.cpp - ${PROJECT_SOURCE_DIR}/src/common/config.cpp + ${PROJECT_SOURCE_DIR}/src/common/db-config.cpp ${PROJECT_SOURCE_DIR}/src/common/config-file.cpp #${PROJECT_SOURCE_DIR}/src/common/file-lock.cpp ${PROJECT_SOURCE_DIR}/src/common/privilege_db.cpp diff --git a/test/privilege_db_fixture.cpp b/test/privilege_db_fixture.cpp index 4643e62..4b352f7 100644 --- a/test/privilege_db_fixture.cpp +++ b/test/privilege_db_fixture.cpp @@ -29,6 +29,7 @@ #include #include +#include #include #include #include diff --git a/test/test_privilege_db_migration.cpp b/test/test_privilege_db_migration.cpp index 56b6a64..7b1a522 100644 --- a/test/test_privilege_db_migration.cpp +++ b/test/test_privilege_db_migration.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include #include "privilege_db.h"