Optimize loading group information. 02/243802/5
authorjin-gyu.kim <jin-gyu.kim@samsung.com>
Thu, 10 Sep 2020 07:11:32 +0000 (07:11 +0000)
committerTomasz Swierczek <t.swierczek@samsung.com>
Mon, 21 Sep 2020 10:53:21 +0000 (10:53 +0000)
Store group ids in a new configuartion file to avoid calculating it every time.
Those are written in $POLICY_PATH/group-id.list when policy rpm is installed.
These changes will speed up about 10 times for calulating group ids.

Change-Id: I0d71a44fdb7513a1c63c107062bfbe344b6889e8

packaging/security-manager.spec
policy/CMakeLists.txt
policy/update_group_id_list.sh.in [new file with mode: 0644]
src/common/include/config.h
src/common/include/utils.h
src/common/utils.cpp
src/nss/nss_securitymanager.cpp
test/test_misc.cpp

index 3cbe2c1a40f21f19bf643238aaa4de9792a8b9e2..9cca6f46af22c13c6eedaf2b6941fffbb810e2d8 100644 (file)
@@ -84,6 +84,7 @@ Requires(post): security-manager = %{version}-%{release}
 Requires(post): cyad
 Requires(post): sqlite
 Requires(post): tizen-platform-config-tools
+Requires(post): security-config
 
 %description policy
 Set of security rules that constitute security policy in the system
@@ -259,6 +260,7 @@ fi
 
 %post policy
 %{_datadir}/%{name}/policy/update.sh
+%{_datadir}/%{name}/policy/update_group_id_list.sh
 %{_bindir}/security-manager-policy-reload
 
 %post -n security-manager-tests
index 68918f714bbd662ae8fdfb4f3e1f6a0632d51f60..bbbab62b9320881232e269e732e76cdc25fa8106 100644 (file)
@@ -24,6 +24,7 @@ SET(FOTA_DIR "${SYSCONF_INSTALL_DIR}/opt/upgrade")
 FILE(GLOB USERTYPE_POLICY_FILES usertype-*.profile)
 
 CONFIGURE_FILE(security-manager-policy-reload.in security-manager-policy-reload @ONLY)
+CONFIGURE_FILE(update_group_id_list.sh.in update_group_id_list.sh @ONLY)
 
 SET(PRIV_MAPPING_TEMPLATE_FILES
     "priv-rules-default-template.smack")
@@ -44,6 +45,7 @@ INSTALL(FILES "privilege-managed-by-systemd-for-daemons.list" DESTINATION ${POLI
 INSTALL(PROGRAMS "update.sh" DESTINATION ${POLICY_INSTALL_DIR})
 INSTALL(DIRECTORY "updates" USE_SOURCE_PERMISSIONS DESTINATION ${POLICY_INSTALL_DIR})
 INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/security-manager-policy-reload DESTINATION ${BIN_INSTALL_DIR})
+INSTALL(PROGRAMS "update_group_id_list.sh" DESTINATION ${POLICY_INSTALL_DIR})
 
 # FOTA updater
 INSTALL(FILES 241.security-manager.policy-update.sh DESTINATION ${FOTA_DIR})
diff --git a/policy/update_group_id_list.sh.in b/policy/update_group_id_list.sh.in
new file mode 100644 (file)
index 0000000..98d775f
--- /dev/null
@@ -0,0 +1,44 @@
+#!/bin/sh -e
+
+#
+# Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved.
+#
+# This file is licensed under the terms of MIT License or the Apache License
+# Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
+# See the LICENSE file or the notice below for Apache License Version 2.0
+# details.
+#
+# 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.
+#
+
+PATH=/bin:/usr/bin:/sbin:/usr/sbin
+POLICY_PATH=@POLICY_INSTALL_DIR@
+PRIVILEGE_GROUP_MAPPING=$POLICY_PATH/privilege-group.list
+PRIVILEGE_SYSTEMD_LIST=$POLICY_PATH/privilege-managed-by-systemd-for-daemons.list
+GROUP_LIST=$POLICY_PATH/group-id.list
+
+# Init group ID list file. If failed, script will be terminated. (In case of RO mount case)
+cat /dev/null > $GROUP_LIST
+
+# Create group ID lists into $GROUP_LIST.
+grep -v '^#' "$PRIVILEGE_GROUP_MAPPING" |
+while read privilege group
+do
+    gid=$(getent group "$group" | cut -d ":" -f3)
+    if [ "$(grep -x $privilege $PRIVILEGE_SYSTEMD_LIST)" == "" ]; then
+        echo "common" "$gid" >> $GROUP_LIST
+    else
+        echo "systemd_managed" "$gid" >> $GROUP_LIST
+    fi
+done
+
index b7c694c0ec9375b145a2907343e73418ead67e48..7596c9a9584d59346065d50fb810b5b3b4b1cc7c 100644 (file)
@@ -47,9 +47,8 @@
 
 /* Policy files */
 
-#define PRIVILEGE_GROUP_LIST_FILE  POLICY_INSTALL_DIR "/privilege-group.list"
 #define PRIVILEGE_MOUNT_LIST_FILE  POLICY_INSTALL_DIR "/privilege-mount.list"
-#define PRIVILEGE_SYSTEMD_LIST_FILE  POLICY_INSTALL_DIR "/privilege-managed-by-systemd-for-daemons.list"
+#define GROUP_ID_FILE POLICY_INSTALL_DIR "/group-id.list"
 
 #define SKEL_DIR                   "/etc/skel"
 
index 95b78089be68637316179b5675cd505a5f60f698..24be37ce819e4dd8b1788ef9c3d2f5f09fbac31c 100644 (file)
@@ -70,12 +70,9 @@ private:
 #endif
 
 // Group operations
-void loadGroups(std::vector<gid_t> &vgroups, std::vector<std::string> *privileges = NULL);
+void loadGroups(std::vector<gid_t> &vgroups, bool is_nss = false);
 int group_vector_to_array(const std::vector<gid_t> &vgroups, gid_t **groups, size_t *groups_count);
 
-// Loading list of privileges that have GIDs managed by systemd for inter-daemon access control
-void loadSystemdManagedPrivileges(std::vector<std::string> &privileges);
-
 // Pointer
 template<typename T>
 std::unique_ptr<T> makeUnique(T *ptr)
index d52d340a3723013150cc85b5b879c9d6ac6f4e03..f30f8a20e18a70710e0457d4c9eade02a2c56eea 100644 (file)
@@ -107,46 +107,14 @@ ScopedTimeStamper::~ScopedTimeStamper()
     LogDebug("Execution of " << m_locationStr << " took " << sec << " seconds");
 }
 
-void loadGroups(std::vector<gid_t> &vgroups, std::vector<std::string> *privileges)
+void loadGroups(std::vector<gid_t> &vgroups, bool is_nss)
 {
-    auto groupsMapData = ConfigFile(PRIVILEGE_GROUP_LIST_FILE).read();
+    auto groupsMapData = ConfigFile(GROUP_ID_FILE).read();
     for (auto &groupsMapEntry : groupsMapData) {
         if (groupsMapEntry.size() != 2)
             continue;
-
-        const std::string &groupName = groupsMapEntry[1];
-        std::vector<char> 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);
-        if (privileges)
-            privileges->emplace_back(std::move(groupsMapEntry[0]));
-    }
-}
-
-void loadSystemdManagedPrivileges(std::vector<std::string> &privileges)
-{
-    auto groupsMapData = ConfigFile(PRIVILEGE_SYSTEMD_LIST_FILE).read();
-    for (auto &privEntry : groupsMapData) {
-        if (privEntry.size() != 1)
-            continue;
-        privileges.emplace_back(std::move(privEntry[0]));
+        if (!is_nss || (is_nss && !groupsMapEntry[0].compare("common")))
+            vgroups.push_back(std::stoi(groupsMapEntry[1]));
     }
 }
 
index ce5e3a45b70b94137b533341b2e4c43d5392984f..eec7fe43c763b608a56d83885a96138002e3a183 100644 (file)
@@ -47,26 +47,10 @@ int security_manager_groups_get_for_daemons_internal(gid_t *&groups, size_t &gro
 {
     using namespace SecurityManager;
     return try_catch([&]() -> int {
-        std::vector<gid_t> vgroups, vdaemongroups;
-        std::vector<std::string> privileges;
-        loadGroups(vgroups, &privileges);
-        if (vgroups.size() != privileges.size())
-            return SECURITY_MANAGER_ERROR_UNKNOWN;  // this should not happen
-        std::vector<std::string> systemdPrivileges;
-        loadSystemdManagedPrivileges(systemdPrivileges);
-        for (unsigned i = 0; i < privileges.size(); ++i) {
-            bool skip = false;
-            for (auto systemPriv: systemdPrivileges)
-                if (privileges[i] == systemPriv) {
-                    skip = true;
-                    break;
-                }
-            if (!skip)
-                vdaemongroups.push_back(vgroups[i]);
-        }
-        return group_vector_to_array(vdaemongroups, &groups, &groups_count);
+        std::vector<gid_t> vgroups;
+        loadGroups(vgroups, true);
+        return group_vector_to_array(vgroups, &groups, &groups_count);
     });
-
 }
 
 } // namespace anonymous
index 72828ca84c51705b0ab0875d4bc90f629157a262..a511463bafaba75e0bf9f7165b77ec291535b7f2 100644 (file)
@@ -103,10 +103,9 @@ POSITIVE_TEST_CASE(T287_groups_loading)
     size_t groups_count = 1;
     BOOST_REQUIRE_NO_THROW(group_vector_to_array(vgroups, &groups, &groups_count));
     BOOST_REQUIRE_MESSAGE(!groups && !groups_count, "Invalid output from group_vector_to_array");
-    BOOST_REQUIRE_NO_THROW(loadGroups(vgroups, &privileges));
+    BOOST_REQUIRE_NO_THROW(loadGroups(vgroups));
     // current configuration has some groups and some privileges
-    BOOST_REQUIRE_MESSAGE(vgroups.size() > 0 && privileges.size() == vgroups.size(),
-                          "Invalid output from loadGroups");
+    BOOST_REQUIRE_MESSAGE(vgroups.size() > 0, "Invalid output from loadGroups");
     BOOST_REQUIRE_NO_THROW(group_vector_to_array(vgroups, &groups, &groups_count));
     auto gPtr2 = makeUnique(groups, free);
     BOOST_REQUIRE_MESSAGE(groups, "NULL returned from group_vector_to_array");
@@ -123,23 +122,17 @@ POSITIVE_TEST_CASE(T288_monotonic_clock)
     BOOST_REQUIRE_MESSAGE(t > 0, "Invalid monotonic time value");
 }
 
-POSITIVE_TEST_CASE(T289_loadSystemdManagedPrivileges)
-{
-    std::vector<std::string> privs;
-    BOOST_REQUIRE_NO_THROW(loadSystemdManagedPrivileges(privs));
-}
-
-NEGATIVE_TEST_CASE(T290_creds)
+NEGATIVE_TEST_CASE(T289_creds)
 {
     BOOST_REQUIRE_THROW(Credentials::getCredentialsFromSocket(-1), Credentials::Exception::SocketError);
 }
 
-NEGATIVE_TEST_CASE(T291_creds)
+NEGATIVE_TEST_CASE(T290_creds)
 {
     BOOST_REQUIRE_THROW(Credentials::getCredentialsFromFd(-1), Credentials::Exception::FdError);
 }
 
-POSITIVE_TEST_CASE(T292_tzplatform_config)
+POSITIVE_TEST_CASE(T291_tzplatform_config)
 {
     TizenPlatformConfig cfg(0);
     BOOST_REQUIRE_NO_THROW(cfg.ctxMakePath(
@@ -165,7 +158,7 @@ POSITIVE_TEST_CASE(T292_tzplatform_config)
                                 "/just a string 1/", "/just a string 2/", "/just a string 3/"));
 }
 
-POSITIVE_TEST_CASE(T293_exception_class)
+POSITIVE_TEST_CASE(T292_exception_class)
 {
         Exception e("path", "function", 1, "message");
         std::string s = Exception::KnownExceptionToString(e);