Add security-manager permissive mode build option - dev_wos 34/316134/4
authorTomasz Swierczek <t.swierczek@samsung.com>
Mon, 15 Apr 2024 14:01:29 +0000 (16:01 +0200)
committerTomasz Swierczek <t.swierczek@samsung.com>
Fri, 13 Dec 2024 08:04:34 +0000 (09:04 +0100)
Usage: gbs <your favourite flags> --define "dev_wos 1".

If not explicitly specified, the option is disabled (switched to 0).

This option is intended only for development, not for release builds.

With this option, security-manager enters "permissive mode"
and doesn't operate on Smack or anything that may be related:
* at launching:
** doesn't change/modify/configure mount namespaces
** doesn't change/modify/configure capabilities
** doesn't change/modify/set Smack labels of app candidate threads
** does set group IDs based on privileges in the Cynara DB
* at app installation:
** doesn't change any Smack labels of files/folders

Other operations (ie. registering apps in the DB) should be performed
as usual.

rules-loader service is only checking the DB and making sure it has
all proper schema applied (DB versioning, etc.) but otherwise,
the one-shot service is not loading any Smack rules.

With this option, the application identification functions that rely
on Smack being the application identifier, that is:

security_manager_identify_app_from_socket
security_manager_identify_app_from_pid

...will return same string default_app_no_Smack_mode as the app pkg ID.

The API function:

security_manager_identify_app_from_cynara_client

...will normally parse Smack label, as its expected that cynara helpers
will be returning the string:

User::Pkg::default_app_no_Smack_mode

...as cynara client.

The API function:

security_manager_app_has_privilege

...will always return success & access granted.

This mode is intended to be used by for bring-up development
of Tizen working in container.

Change-Id: I24c15bb51f87faab3ac14b9dae5e296d682bd768

CMakeLists.txt
packaging/security-manager.spec
src/client/client-security-manager.cpp
src/common/credentials.cpp
src/common/service_impl.cpp
src/common/smack-rules.cpp
src/server/rules-loader/security-manager-rules-loader.cpp
src/server/service/service.cpp

index 94c7978debd33f850deb434ebe01aa585d66df62..a2ade2e33ddcb3ad3da831d54f8ed7f58eb03288 100644 (file)
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013-2020 Samsung Electronics Co., Ltd. All rights reserved.
+# Copyright (c) 2013-2024 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.
@@ -107,7 +107,6 @@ ADD_DEFINITIONS("-fno-lto")                     # Mitigating issues with functio
 STRING(REGEX MATCH "([^.]*)" API_VERSION "${VERSION}")
 ADD_DEFINITIONS("-DAPI_VERSION=\"$(API_VERSION)\"")
 
-ADD_DEFINITIONS("-DSMACK_ENABLED")
 ADD_DEFINITIONS("-DASKUSER_ENABLED")
 
 OPTION(DPL_WITH_DLOG "DPL DLOG backend" ON)
@@ -115,6 +114,13 @@ OPTION(DPL_WITH_SYSTEMD_JOURNAL "DPL systemd-journal backend" OFF)
 
 ADD_DEFINITIONS("-DBUILD_TYPE_${CMAKE_BUILD_TYPE}")
 
+# Module needs to know if it should work with Smack or without it
+# (regardless of runtime-detection of the option which is used
+# for detecting image-creation offline mode)
+IF(SUPPORT_SMACK)
+    ADD_DEFINITIONS("-DSMACK_ENABLED")
+ENDIF()
+
 SET(INCLUDE_PATH ${PROJECT_SOURCE_DIR}/src/include)
 SET(COMMON_PATH  ${PROJECT_SOURCE_DIR}/src/common)
 SET(CLIENT_PATH  ${PROJECT_SOURCE_DIR}/src/client)
index 226af1a92671eb4d760a8111c2eedc0b751a6ae4..b61ca9091f3ab036a810775b3a23a09e4a437e00 100644 (file)
@@ -149,6 +149,7 @@ export LDFLAGS+="-Wl,--rpath=%{_libdir}"
 
 %global db_test_dir %{_datadir}/sm-db-test
 %global coverage_dir %{_datadir}/security-manager-coverage
+%global sm_permissive_mode %{?dev_wos:%dev_wos}%{!?dev_wos:0}
 
 %cmake . \
        -DVERSION=%{version} \
@@ -160,6 +161,9 @@ export LDFLAGS+="-Wl,--rpath=%{_libdir}"
        -DDB_LOGS=OFF \
        -DCMAKE_BUILD_TYPE=%{build_type} \
        -DCMAKE_VERBOSE_MAKEFILE=ON \
+%if %{sm_permissive_mode} == 0
+       -DSUPPORT_SMACK="ON"\
+%endif
        -DCOVERAGE_DIR=%{coverage_dir}
 make %{?jobs:-j%jobs}
 
index 3ceec256084f3a148cfc141398757ab3a0ba3da2..6c50cfb48d518538f1415c90370e1059cf99bb95 100644 (file)
@@ -1015,6 +1015,11 @@ int security_manager_drop_process_privileges(void)
 {
     LogDebug("security_manager_drop_process_privileges() called");
 
+    if (!smack_check()) {
+        LogWarning("Running in no-smack mode, not dropping capabilities");
+        return SECURITY_MANAGER_SUCCESS;
+    }
+
     int ret;
     cap_t cap = cap_init();
     if (!cap) {
@@ -1117,6 +1122,11 @@ int security_manager_prepare_app_candidate(void)
 {
     LogDebug("security_manager_prepare_app_candidate() called");
 
+    if (!smack_check()) {
+        LogWarning("Running in no-smack mode, exiting earlier without setting up namespaces");
+        return SECURITY_MANAGER_SUCCESS;
+    }
+
     auto dir = opendir("/proc/self/task");
     if (!dir) {
         LogError("Unable to get number of threads");
@@ -1221,6 +1231,11 @@ int security_manager_prepare_app2(const char *app_name, const char *subsession_i
             return ret;
         }
 
+        if (!smack_check()) {
+            LogWarning("Running in no-smack mode, exiting with success from prepare_app2 - not setting namespaces any further, or Smack, or caps");
+            return (int)SECURITY_MANAGER_SUCCESS;
+        }
+
         ret = security_manager_setup_namespace_internal(privilegePathMap, pkgName,
                 prepareAppFlags & PREPARE_APP_SHARED_RO_FLAG, privPathsStatusVector, appLabel, subsession_id);
         if (ret != SECURITY_MANAGER_SUCCESS) {
@@ -1252,6 +1267,11 @@ int security_manager_cleanup_app(const char *app_name, uid_t uid, pid_t pid)
             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
         }
 
+        if (!smack_check()) {
+            LogWarning("Running in no-smack mode, not cleaning namespaces");
+            return SECURITY_MANAGER_SUCCESS;
+        }
+
         ClientRequest request(SecurityModuleCall::APP_CLEAN_NAMESPACE);
         return request.send(std::string(app_name), uid, pid).getStatus();
     });
@@ -1748,6 +1768,11 @@ SECURITY_MANAGER_API
 int security_manager_identify_app_from_socket(int sockfd, char **pkg_name, char **app_name)
 {
     return try_catch([&] {
+        if(!smack_check()) {
+            LogWarning("Running in no-smack mode, returning static pkg_name default_app_no_Smack_mode & empty app_name");
+            *pkg_name = strdup("default_app_no_Smack_mode");
+            return *pkg_name ? (int)SECURITY_MANAGER_SUCCESS : (int)SECURITY_MANAGER_ERROR_MEMORY;
+        }
         return security_manager_identify_app([&] {
             return SmackLabels::getSmackLabelFromSocket(sockfd);
         }, pkg_name, app_name);
@@ -1758,6 +1783,11 @@ SECURITY_MANAGER_API
 int security_manager_identify_app_from_pid(pid_t pid, char **pkg_name, char **app_name)
 {
     return try_catch([&] {
+        if(!smack_check()) {
+            LogWarning("Running in no-smack mode, returning static pkg_name default_app_no_Smack_mode & empty app_name");
+            *pkg_name = strdup("default_app_no_Smack_mode");
+            return *pkg_name ? (int)SECURITY_MANAGER_SUCCESS : (int)SECURITY_MANAGER_ERROR_MEMORY;
+        }
         return security_manager_identify_app([&] {
             return SmackLabels::getSmackLabelFromPid(pid);
         }, pkg_name, app_name);
@@ -1775,6 +1805,7 @@ int security_manager_identify_app_from_cynara_client(const char *client, char **
             LogError("Both pkg_name and app_name are NULL");
             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
         }
+        // assuming Cynara will return - from helpers - User::Pkg::default_app_no_Smack_mode, this should just work
         return get_app_and_pkg_id_from_smack_label(client, pkg_name, app_name);
     });
 }
@@ -1783,6 +1814,14 @@ SECURITY_MANAGER_API
 int security_manager_app_has_privilege(const char *app_name, const char *privilege,
                                        uid_t uid, int *result)
 {
+    if (!result || !app_name || !privilege) {
+        return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+    }
+    if (!smack_check()) {
+        LogWarning("Running in no-smack mode, treating all apps as having all privileges");
+        *result = 1;
+        return SECURITY_MANAGER_SUCCESS;
+    }
     using namespace SecurityManager;
     return try_catch([&]() -> int {
         ClientRequest request(SecurityModuleCall::APP_HAS_PRIVILEGE);
@@ -1799,6 +1838,11 @@ int security_manager_app_has_privilege(const char *app_name, const char *privile
 SECURITY_MANAGER_API
 int security_manager_private_sharing_req_new(private_sharing_req **pp_req)
 {
+    if (!smack_check()) {
+        LogWarning("Running in no-smack mode, private sharing is a no-op, due to no Smack");
+        return SECURITY_MANAGER_SUCCESS;
+    }
+
     if (!pp_req)
             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
 
@@ -1814,6 +1858,10 @@ int security_manager_private_sharing_req_new(private_sharing_req **pp_req)
 SECURITY_MANAGER_API
 void security_manager_private_sharing_req_free(private_sharing_req *p_req)
 {
+    if (!smack_check()) {
+        LogWarning("Running in no-smack mode, private sharing is a no-op, due to no Smack");
+        return;
+    }
     delete p_req;
 }
 
@@ -1821,6 +1869,11 @@ SECURITY_MANAGER_API
 int security_manager_private_sharing_req_set_owner_appid(
     private_sharing_req *p_req, const char *app_name)
 {
+    if (!smack_check()) {
+        LogWarning("Running in no-smack mode, private sharing is a no-op, due to no Smack");
+        return SECURITY_MANAGER_SUCCESS;
+    }
+
     return try_catch([&] {
         if (!p_req || !app_name)
                 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
@@ -1833,6 +1886,11 @@ SECURITY_MANAGER_API
 int security_manager_private_sharing_req_set_target_appid(
     private_sharing_req *p_req, const char *app_name)
 {
+    if (!smack_check()) {
+        LogWarning("Running in no-smack mode, private sharing is a no-op, due to no Smack");
+        return SECURITY_MANAGER_SUCCESS;
+    }
+
     return try_catch([&] {
         if (!p_req || !app_name)
                 return SECURITY_MANAGER_ERROR_INPUT_PARAM;
@@ -1846,6 +1904,11 @@ int security_manager_private_sharing_req_add_paths(private_sharing_req *p_req,
                                                    const char **pp_paths,
                                                    size_t path_count)
 {
+    if (!smack_check()) {
+        LogWarning("Running in no-smack mode, private sharing is a no-op, due to no Smack");
+        return SECURITY_MANAGER_SUCCESS;
+    }
+
     return try_catch([&] {
         if (!p_req || !pp_paths)
             return SECURITY_MANAGER_ERROR_INPUT_PARAM;
@@ -1859,6 +1922,11 @@ int security_manager_private_sharing_req_add_paths(private_sharing_req *p_req,
 SECURITY_MANAGER_API
 int security_manager_private_sharing_apply(const private_sharing_req *p_req)
 {
+    if (!smack_check()) {
+        LogWarning("Running in no-smack mode, private sharing is a no-op, due to no Smack");
+        return SECURITY_MANAGER_SUCCESS;
+    }
+
     using namespace SecurityManager;
     return try_catch([&]() -> int {
         if (!p_req)
@@ -1874,6 +1942,11 @@ int security_manager_private_sharing_apply(const private_sharing_req *p_req)
 SECURITY_MANAGER_API
 int security_manager_private_sharing_drop(const private_sharing_req *p_req)
 {
+    if (!smack_check()) {
+        LogWarning("Running in no-smack mode, private sharing is a no-op, due to no Smack");
+        return SECURITY_MANAGER_SUCCESS;
+    }
+
     using namespace SecurityManager;
     return try_catch([&]() -> int {
         if (!p_req)
index 7785c99ea1163bbcaf453400693c0f6a2b885430..9005282697ef4eb73c7c56b10357a2cb9391f23f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2016-2024 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.
@@ -49,7 +49,7 @@ Credentials Credentials::getCredentialsFromSocket(int sock)
     if (getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &cr, &len) == -1)
         ThrowMsg(Exception::SocketError, "Failed to read peer credentials for sockfd " << sock);
 
-    return Credentials(cr.pid, cr.uid, cr.gid, SmackLabels::getSmackLabelFromSocket(sock));
+    return Credentials(cr.pid, cr.uid, cr.gid, smack_check() ? SmackLabels::getSmackLabelFromSocket(sock) : "");
 }
 
 Credentials Credentials::getCredentialsFromFd(int fd)
@@ -58,7 +58,7 @@ Credentials Credentials::getCredentialsFromFd(int fd)
     if (-1 == fstat(fd, &buf))
         ThrowMsg(Exception::FdError, "Failed to read credentials from filefd " << fd);
 
-    return Credentials(-1, buf.st_uid, buf.st_gid, SmackLabels::getSmackLabelFromFd(fd));
+    return Credentials(-1, buf.st_uid, buf.st_gid, smack_check() ? SmackLabels::getSmackLabelFromFd(fd) : "");
 }
 
 } // namespace SecurityManager
index 95f00248849d1fb005ad845db57997ab35582795..6eaf67663d9f24a6278ebbdf9f5469a4aa763d04 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2023 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 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.
@@ -51,6 +51,7 @@
 #include "privilege_db.h"
 #include "cynara.h"
 #include "permissible-set.h"
+#include "smack-check.h"
 #include "smack-exceptions.h"
 #include "smack-rules.h"
 #include "smack-labels.h"
@@ -176,7 +177,7 @@ ServiceImpl::ServiceImpl(Offline offline) :
     m_privilegeDb.GetGroupsRelatedPrivileges(group_privileges);
     m_privilegeGids.init(group_privileges);
 
-    if (!underlying(offline)) {
+    if (!underlying(offline) && smack_check()) {
         const auto checkProperDropFlags = CheckProperDrop::computeFlags();
         if (checkProperDropFlags < 0)
             ThrowMsg(FS::Exception::FileError, "Error computing CheckProperDrop flags."
@@ -349,6 +350,16 @@ int ServiceImpl::labelPaths(const pkg_paths &paths,
                             bool isSharedRO)
 {
     try {
+
+        if (!smack_check()) {
+            LogWarning("Running in no-smack mode, not labeling any paths");
+            if (!m_privilegeDb.PkgNameExists(pkgName)) {
+                LogError("No such package: " << pkgName);
+                return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+            }
+            return SECURITY_MANAGER_SUCCESS;
+        }
+
         std::string authorHash;
         m_privilegeDb.GetPkgAuthorHash(pkgName, authorHash);
 
@@ -505,6 +516,11 @@ int ServiceImpl::appInstallSmackRules(app_inst_req &req, InstallHelper &ih)
     std::string authorHash = std::string();
     Smack::Labels pkgLabels;
 
+    if (!smack_check()) {
+        LogWarning("Running in no-smack mode, not installing any Smack rules");
+        return SECURITY_MANAGER_SUCCESS;
+    }
+
     try {
         m_privilegeDb.GetPkgAuthorHash(req.pkgName, authorHash);
 
@@ -2407,7 +2423,7 @@ int ServiceImpl::prepareApp(const Credentials &creds, const std::string &appName
 
         LogWarning("GetPkgAuthorHash returned : " << authorHash);
 
-        if (m_smackRules.isPrivilegeMappingEnabled()) {
+        if (m_smackRules.isPrivilegeMappingEnabled() && smack_check()) {
             // We have to remove all possible privilege related Smack rules, because application
             // policy might have changed from last prepareApp
             // (e.g. application new version was installed)
@@ -2428,6 +2444,11 @@ int ServiceImpl::prepareApp(const Credentials &creds, const std::string &appName
 
         LogWarning("getForbiddenAndAllowedGroups returned: " << ret);
 
+        if (!smack_check()) {
+            LogWarning("Running in no-smack mode, exiting without setting up namespaces");
+            return ret;
+        }
+
         return ret != SECURITY_MANAGER_SUCCESS ? ret
             : appSetupNamespace(creds, label, privPathsVector, privPathsStatusVector);
     } catch (const FS::Exception::Base &e) {
index 733e5e9259099c3ed68713b6b591a88ca781e5ec..58a288506fdca342a03a0db6d99f0d8cba84d0df 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 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.
@@ -302,7 +302,8 @@ void SmackRules::uninstallPackageRules(const std::string &pkgName,
     addFromTemplate(smackRules, TemplateManager::Type::PKG_RULES_TEMPLATE,
                     std::string(), pkgName, std::string());
     generatePackageCrossDeps(smackRules, pkgLabels);
-    smackRules.clear();
+    if (smack_check())
+        smackRules.clear();
 }
 
 void SmackRules::uninstallApplicationRules(
@@ -315,8 +316,10 @@ void SmackRules::uninstallApplicationRules(
                     appLabel, pkgName, authorHash);
     if (isPrivilegeMappingEnabled())
         addPrivilegesRules(smackRules, appLabel, pkgName, authorHash, m_templateMgr.getAllMappedPrivs());
-    smackRules.clear();
-    SmackLabels::revokeSubject(appLabel);
+    if (smack_check()) {
+        smackRules.clear();
+        SmackLabels::revokeSubject(appLabel);
+    }
 }
 
 void SmackRules::uninstallAuthorRules(const std::string &authorHash)
@@ -324,7 +327,8 @@ void SmackRules::uninstallAuthorRules(const std::string &authorHash)
     SmackAccesses smackRules;
     addFromTemplate(smackRules, TemplateManager::Type::AUTHOR_RULES_TEMPLATE,
                     std::string(), std::string(), authorHash);
-    smackRules.clear();
+    if (smack_check())
+        smackRules.clear();
 }
 
 void SmackRules::applyPrivateSharingRules(
@@ -351,7 +355,8 @@ void SmackRules::applyPrivateSharingRules(
         rules.add(SMACK_SYSTEM_PRIVILEGED, pathLabel, SMACK_APP_PATH_SYSTEM_PERMS);
     }
     rules.add(targetLabel, pathLabel, SMACK_APP_PATH_TARGET_PERMS);
-    rules.apply();
+    if (smack_check())
+        rules.apply();
 }
 
 void SmackRules::dropPrivateSharingRules(
@@ -377,7 +382,8 @@ void SmackRules::dropPrivateSharingRules(
         rules.addModify(SMACK_SYSTEM_PRIVILEGED, pathLabel, "", SMACK_APP_PATH_SYSTEM_PERMS);
     }
     rules.addModify(targetLabel, pathLabel, "", SMACK_APP_PATH_TARGET_PERMS);
-    rules.apply();
+    if (smack_check())
+        rules.apply();
 }
 
 } // namespace SecurityManager
index e569ab87cece9e93fc768d943da4cf4b3a3bc608..ea8efb515db37f2aa9c1f20a8dfe541551a8665b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2023 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2018-2024 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.
@@ -40,6 +40,7 @@
 
 #include <config.h>
 #include <db-config.h>
+#include <smack-check.h>
 #include <testconfig.h>
 #include <utils.h>
 
@@ -63,6 +64,16 @@ namespace {
 static_assert(dbVersion == arraySize(dbUpdateScript));
 static_assert(allTrue(dbUpdateScript));
 
+// we don't want to add more files to speed up operation & make binary smaller
+int smack_simple_check(void)
+{
+#ifdef SMACK_ENABLED
+    return 1;
+#else
+    return 0;
+#endif
+}
+
 // the loader is compiled in two variants
 // * the default (TEST_LOADER not defined)
 // * for testing (TEST_LOADER defined)
@@ -1130,7 +1141,8 @@ int main(int argc, char *argv[]) {
     }
 
     // database bringup successful, stop now if not going to write rules
-    if (unlikely(noLoad2) || (testLoader && unlikely(fallbackOnly)))
+    // also, stop of working in no-smack env.
+    if (unlikely(noLoad2) || (testLoader && unlikely(fallbackOnly)) || !smack_simple_check())
         return EXIT_SUCCESS;
 
     // open load2 for writing
index 4545de2912ac7e3a674034ae55201b53126b0ead..fe0a19b2b22d8ae2c792d26712c269db4eb00fc4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2023 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 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.
@@ -36,6 +36,7 @@
 #include <connection.h>
 #include <protocols.h>
 #include <service.h>
+#include <smack-check.h>
 #include <utils.h>
 
 namespace SecurityManager {
@@ -58,6 +59,10 @@ void Service::processEvent(Event &&msg)
         int call_type_int;
         Deserialization::Deserialize(msg.buffer, call_type_int);
         SecurityModuleCall call_type = static_cast<SecurityModuleCall>(call_type_int);
+        if (!smack_check()) {
+            LogWarning("Running in no-smack mode, treating connection as authenticated - privileges will not be checked!");
+            msg.creds.authenticated = true;
+        }
         LogWarning("Processing event from client - smack label: " << msg.creds.label << ", pid: " << msg.creds.pid);
         LOG_EXECUTION_TIME(SecurityModuleCallToString(call_type), msg.creds);
         switch (call_type) {