Merge branch 'ckm' into tizen 60/223060/1
authorDariusz Michaluk <d.michaluk@samsung.com>
Wed, 22 Jan 2020 12:17:02 +0000 (13:17 +0100)
committerDariusz Michaluk <d.michaluk@samsung.com>
Wed, 22 Jan 2020 12:17:02 +0000 (13:17 +0100)
Change-Id: Iac9d5cc6393e8598a33c783aabff77006046b187

26 files changed:
CMakeLists.txt
src/ckm/unprivileged/main.cpp
src/common/app_install_helper.cpp
src/common/app_install_helper.h
src/common/label_generator.cpp
src/common/label_generator.h
src/common/scoped_installer.h
src/common/sm_api.cpp
src/common/sm_api.h
src/common/sm_request.cpp
src/common/sm_request.h
src/common/synchronization_pipe.cpp
src/common/synchronization_pipe.h
src/common/tests_common.h
src/cynara-tests/common/cynara_test_client_async_client.cpp
src/framework/src/assert.cpp
src/framework/src/test_runner.cpp
src/security-manager-tests/CMakeLists.txt
src/security-manager-tests/common/sm_commons.cpp
src/security-manager-tests/common/sm_commons.h
src/security-manager-tests/common/template_parser.cpp [new file with mode: 0644]
src/security-manager-tests/common/template_parser.h [new file with mode: 0644]
src/security-manager-tests/test_cases.cpp
src/security-manager-tests/test_cases_prepare_app.cpp
src/security-manager-tests/test_cases_public_sharing.cpp
src/security-manager-tests/test_cases_register_paths.cpp

index 2c6f1e0..9135436 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2012-2015 Samsung Electronics Co., Ltd All Rights Reserved
+# Copyright (c) 2012-2020 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.
@@ -83,6 +83,7 @@ ADD_DEFINITIONS("-Wextra")                      # Generate even more extra warni
 ADD_DEFINITIONS("-Wno-variadic-macros")         # Inhibit variadic macros warnings (needed for ORM)
 ADD_DEFINITIONS("-Wno-deprecated")               # No warnings about deprecated features
 ADD_DEFINITIONS("-Wno-deprecated-declarations")               # No warnings about deprecated features
+ADD_DEFINITIONS("-Wno-implicit-fallthrough")    # No warnings about switc() statements, often done on purpose
 ADD_DEFINITIONS("-DCYNARA_DB_DIR=\"${CYNARA_DB_DIR}\"")
 ADD_DEFINITIONS("-DAPP_USER=\"${APP_USER}\"")
 
index 9964dfb..b5e2b93 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (c) 2016 - 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *  Copyright (c) 2016-2020 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.
@@ -1303,7 +1303,6 @@ RUNNER_TEST(T13129_get_chain)
     auto manager = CKM::Manager::create();
 
     RUNNER_ASSERT_MSG(NULL != cert.get(), "Certificate should not be empty");
-    RUNNER_ASSERT_MSG(false != cert1.get(), "Certificate should not be empty");
 
     tmp = manager->getCertificateChain(cert,
                                        EMPTY_CERT_VECTOR,
index 093da6b..1f6e0e8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-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.
@@ -34,6 +34,9 @@
 #include "app_install_helper.h"
 
 namespace {
+
+const gid_t FILE_GROUP = 100;
+
     std::string genSkelPath() {
         static std::string skelPkgDir;
         if (!skelPkgDir.empty())
@@ -94,6 +97,18 @@ void AppInstallHelper::setInstallPath(RootType type) const {
     case RootType::SKEL:
         info.path = genSkelPath() + "/" + getPkgId();
         break;
+    case RootType::SHARED:
+        if (m_isLocal)
+            info.path = TzPlatformConfig::appDirPath(getUID()) + ".shared/" + getPkgId();
+        else
+            info.path = TzPlatformConfig::globalAppDir() + "/.shared/" + getPkgId();
+        break;
+    case RootType::SHARED_TMP:
+        if (m_isLocal)
+            info.path = TzPlatformConfig::appDirPath(getUID()) + ".shared_tmp/" + getPkgId();
+        else
+            info.path = TzPlatformConfig::globalAppDir() + "/.shared_tmp/" + getPkgId();
+        break;
     }
 }
 
@@ -110,7 +125,7 @@ std::string AppInstallHelper::getPath(app_install_path_type smType, PathType pTy
         break;
     case PathType::FILE:
         // put files in the directory of the same type
-        path = getInstallDir(rType) + "/" + typeToPath.at(smType) + "_dir0/" + typeToPath.at(smType) + std::to_string(i);
+        path = getPath(smType, PathType::DIR, 0, rType) + "/" + typeToPath.at(smType) + std::to_string(i);
         break;
     }
     return path;
@@ -137,7 +152,11 @@ std::string AppInstallHelper::getPrivatePath(int i, RootType type) const {
 }
 
 std::string AppInstallHelper::getSharedRODir(int i, RootType type) const {
-    return getPath(SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO, PathType::DIR, i, type);
+return getPath(SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO, PathType::DIR, i, type);
+}
+
+std::string AppInstallHelper::getSharedROPath(int i, RootType type) const {
+    return getPath(SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO, PathType::FILE, i, type);
 }
 
 std::string AppInstallHelper::getAppId() const {
@@ -167,8 +186,8 @@ int AppInstallHelper::getGID() const {
 bool AppInstallHelper::createFile(app_install_path_type smType, const std::string &path) {
     if (creat(path.c_str(), 0751) == 0) {
         // Local paths need user change
-        m_fileTypeMap[smType].push_back(std::move(path));
-        if (!m_isLocal || chown(path.c_str(), m_uidGid, m_uidGid) == 0)
+        m_fileTypeMap[smType].push_back(path);
+        if (!m_isLocal || chown(path.c_str(), m_uidGid, FILE_GROUP) == 0)
             return true;
     }
     return false;
@@ -178,8 +197,8 @@ bool AppInstallHelper::createDir(app_install_path_type smType, const std::string
     mktreeSafe(path, 0777);
     // Dont pass base pkg dirs to SM, because transmute will be forced on RO subdirs
     if (!isBasePath)
-        m_dirTypeMap[smType].push_back(std::move(path));
-    if (!m_isLocal || chown(path.c_str(), m_uidGid, m_uidGid) == 0)
+        m_dirTypeMap[smType].push_back(path);
+    if (!m_isLocal || chown(path.c_str(), m_uidGid, FILE_GROUP) == 0)
         return true;
 
     return false;
@@ -202,12 +221,25 @@ void AppInstallHelper::createPath(app_install_path_type smType, PathType pType,
         createDir(smType, path);
         break;
     case PathType::FILE:
-        createPath(smType, PathType::DIR, i, rType);
+        createPath(smType, PathType::DIR, 0, rType);
         createFile(smType, path);
         break;
     }
 }
 
+void AppInstallHelper::createDirLink(app_install_path_type smType, const std::string &dest, int i,
+                                     RootType rType)
+{
+    createInstallDir(rType);
+    std::string linkPath = getPath(smType, PathType::DIR, i, rType);
+    if (symlink(dest.c_str(), linkPath.c_str()) == 0) {
+        m_fileTypeMap[smType].push_back(linkPath);
+        if (m_isLocal) {
+            chown(linkPath.c_str(), m_uidGid, FILE_GROUP);
+        }
+    }
+}
+
 void AppInstallHelper::createTrustedDir(int i, RootType type) {
     createPath(SECURITY_MANAGER_PATH_TRUSTED_RW, PathType::DIR, i, type);
 }
@@ -225,7 +257,14 @@ void AppInstallHelper::createPrivateFile(int i, RootType type) {
 }
 
 void AppInstallHelper::createSharedRODir(int i, RootType type) {
-    createPath(SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO, PathType::DIR, i, type);
+    createPath(SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO, PathType::DIR, i, RootType::SHARED);
+    createInstallDir(RootType::SHARED_TMP);
+    auto linkPath = getSharedRODir(i, RootType::SHARED);
+    createDirLink(SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO, linkPath, i, type);
+}
+
+void AppInstallHelper::createSharedROFile(int i, RootType type) {
+    createPath(SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO, PathType::FILE, i, type);
 }
 
 void AppInstallHelper::createPrivateRODir(int i, RootType type) {
index e238261..cefeb71 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-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.
@@ -90,7 +90,9 @@ struct AppInstallHelper {
     enum RootType {
         BASE,
         SKEL,
-        EXTENDED
+        EXTENDED,
+        SHARED,
+        SHARED_TMP
     };
 
     enum PathType {
@@ -107,6 +109,7 @@ struct AppInstallHelper {
     void createPublicDir(RootType type = RootType::BASE);
     void createPrivateFile(int i = 0, RootType type = RootType::BASE);
     void createSharedRODir(int i = 0, RootType type = RootType::BASE);
+    void createSharedROFile(int i = 0, RootType type = RootType::BASE);
     void createPrivateRODir(int i = 0, RootType type = RootType::BASE);
     void removePaths();
 
@@ -121,6 +124,7 @@ struct AppInstallHelper {
     std::string getPublicDir(RootType type = RootType::BASE) const;
     std::string getPrivatePath(int i = 0, RootType type = RootType::BASE) const;
     std::string getSharedRODir(int i = 0, RootType type = RootType::BASE) const;
+    std::string getSharedROPath(int i = 0, RootType type = RootType::BASE) const;
     const TypePathsMap& getDirsMap() const;
     const TypePathsMap& getFilesMap() const;
 
@@ -155,6 +159,8 @@ protected:
 
     bool createFile(app_install_path_type smType, const std::string &path);
     bool createDir(app_install_path_type smType, const std::string &path, bool isBasePath = false);
+    void createDirLink(app_install_path_type smType, const std::string &dest, int i = 0,
+                       RootType rType = RootType::BASE);
     void createInstallDir(RootType type);
 
     std::string m_appName;
index 6fc5140..dbd00b5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2017-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.
@@ -36,11 +36,6 @@ std::string generatePathROLabel(const std::string &pkgId)
     return generatePathRWLabel(pkgId) + "::RO";
 }
 
-std::string generatePathSharedROLabel(const std::string &pkgId)
-{
-    return generatePathRWLabel(pkgId) + "::SharedRO";
-}
-
 std::string generatePathTrustedLabel(int64_t authorId)
 {
     return "User::Author::" + std::to_string(authorId);
@@ -50,3 +45,8 @@ std::string getPublicPathLabel()
 {
     return "User::Home";
 }
+
+std::string getSharedROPathLabel()
+{
+    return "User::App::Shared";
+}
index 8c99ed4..b4af291 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2017-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.
@@ -20,6 +20,6 @@
 std::string generateProcessLabel(const std::string &appId, const std::string &pkgId, bool isHybrid = false);
 std::string generatePathRWLabel(const std::string &pkgId);
 std::string generatePathROLabel(const std::string &pkgId);
-std::string generatePathSharedROLabel(const std::string &pkgId);
 std::string generatePathTrustedLabel(int64_t authorId);
 std::string getPublicPathLabel();
+std::string getSharedROPathLabel();
index 4a0ff06..82175ce 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2016-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.
@@ -36,7 +36,7 @@
 class ScopedInstaller {
 public:
     ScopedInstaller(const AppInstallHelper &app, bool requestUid = true)
-        : m_appId(app.getAppId()),
+        : m_appIds({app.getAppId()}),
           m_uid(app.getUID()),
           m_installType(app.getInstallType()),
           m_shouldUninstall(true),
@@ -70,9 +70,30 @@ public:
         SecurityManagerTest::Api::install(instReq);
     }
 
+    ScopedInstaller(const std::vector<std::string> &appIds, const std::string &pkgId)
+        : m_appIds(appIds),
+          m_uid(0),
+          m_installType(SM_APP_INSTALL_NONE),
+          m_shouldUninstall(true),
+          m_requestUid(false),
+          m_creatorPid(getpid())
+    {
+        SecurityManagerTest::InstallRequest instReq;
+
+        instReq.setPkgId(pkgId);
+        for (unsigned int i = 0; i < appIds.size(); i++) {
+            if (i > 0)
+                instReq.nextApp();
+
+            instReq.setAppId(appIds[i]);
+        }
+
+        SecurityManagerTest::Api::install(instReq);
+    }
+
     ScopedInstaller(const ScopedInstaller &) = delete;
     ScopedInstaller(ScopedInstaller &&other)
-        : m_appId(std::move(other.m_appId)),
+        : m_appIds(std::move(other.m_appIds)),
           m_uid(other.m_uid),
           m_installType(other.m_installType),
           m_shouldUninstall(other.m_shouldUninstall),
@@ -97,7 +118,12 @@ public:
         if (!m_shouldUninstall)
             return;
         SecurityManagerTest::InstallRequest uninstReq;
-        uninstReq.setAppId(m_appId);
+        for (unsigned int i = 0; i < m_appIds.size(); i++) {
+            if (i > 0)
+                uninstReq.nextApp();
+
+            uninstReq.setAppId(m_appIds[i]);
+        }
         if (m_requestUid)
             uninstReq.setUid(m_uid);
         if (m_installType != SM_APP_INSTALL_NONE)
@@ -107,7 +133,7 @@ public:
     }
 
 protected:
-    std::string m_appId;
+    std::vector<std::string> m_appIds;
     uid_t m_uid;
     app_install_type m_installType;
     bool m_shouldUninstall;
index e8c5bba..4516755 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-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.
@@ -123,6 +123,15 @@ void dropProcessPrivileges(lib_retcode expectedResult)
                           << " Expected result: " << expectedResult);
 }
 
+void prepareAppCandidate(lib_retcode expectedResult)
+{
+    int result = security_manager_prepare_app_candidate();
+    RUNNER_ASSERT_MSG((lib_retcode) result == expectedResult,
+                      "preparing app candidate process returned wrong value."
+                          << " Result: " << result << ";"
+                          << " Expected result: " << expectedResult);
+}
+
 void prepareApp(const std::string &appId, lib_retcode expectedResult)
 {
     int result = security_manager_prepare_app(appId.c_str());
index 1b4d2e1..a623ab8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-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.
@@ -37,6 +37,7 @@ void setProcessLabel(const std::string &appId, lib_retcode expectedResult = SECU
 void setProcessGroups(const std::string &appId, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
 void dropProcessPrivileges(lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
 void prepareApp(const std::string &appId, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
+void prepareAppCandidate(lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
 void cleanupApp(const std::string &appId, uid_t uid, pid_t pid, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
 void addUser(const UserRequest &request, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
 void deleteUser(const UserRequest &request, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
index 6e06150..b6fa1a1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-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.
@@ -70,7 +70,6 @@ void InstallRequest::setAppId(std::string appId, lib_retcode expectedResult)
                           << " App id: " << appId << ";"
                           << " Result: " << result << ";"
                           << " Expected result: " << expectedResult);
-    m_appId = std::move(appId);
 }
 
 void InstallRequest::setPkgId(std::string pkgId, lib_retcode expectedResult)
@@ -167,10 +166,17 @@ void InstallRequest::setHybrid(lib_retcode expectedResult)
                        << " Expected result: " << expectedResult);
 }
 
+void InstallRequest::nextApp(lib_retcode expectedResult)
+{
+    int result = security_manager_app_inst_req_next(m_req);
+    RUNNER_ASSERT_MSG((lib_retcode)result == expectedResult,
+                        "security_manager_app_inst_req_next() returned wrong value."
+                        << " Result: " << result << ";"
+                        << " Expected result: " << expectedResult);
+}
+
 std::ostream& operator<<(std::ostream &os, const InstallRequest &request)
 {
-    if (!request.m_appId.empty())
-        os << "app id: " << request.m_appId << "; ";
     if (!request.m_pkgId.empty())
         os << "pkg id: " << request.m_pkgId << "; ";
     if (!request.m_privileges.empty()) {
index 4efb5c9..d58d43e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-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.
@@ -42,7 +42,6 @@ public:
     InstallRequest& operator=(const InstallRequest&) = delete;
     InstallRequest(InstallRequest &&other)
         : m_req(std::move(other.m_req)),
-          m_appId(std::move(other.m_appId)),
           m_pkgId(std::move(other.m_pkgId)),
           m_authorId(std::move(other.m_authorId)),
           m_privileges(std::move(other.m_privileges)),
@@ -67,6 +66,7 @@ public:
     void setAuthorId(std::string authorId, lib_retcode expectedResult= SECURITY_MANAGER_SUCCESS);
     void setInstallType(const enum app_install_type &type, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
     void setHybrid(lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
+    void nextApp(lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
     std::string getPkgId() const { return m_pkgId; }
     std::string getAppTizenVersion() const { return m_tizenVer; }
     app_inst_req *get() { return m_req; }
@@ -77,7 +77,6 @@ private:
     app_inst_req *m_req;
 
     std::string m_tizenVer;
-    std::string m_appId;
     std::string m_pkgId;
     std::string m_authorId;
     PrivilegeVector m_privileges;
index dcf9d30..8336767 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015-2020 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.
@@ -20,6 +20,7 @@
  * @brief       A crippled abstraction of widely praised, but often misused communication mechanism
  */
 
+#include <poll.h>
 #include <stdexcept>
 #include <unistd.h>
 
@@ -76,15 +77,33 @@ void SynchronizationPipe::claimChildEp() {
 }
 
 void SynchronizationPipe::post() {
-    RUNNER_ASSERT_MSG(m_epClaimed == true, "Endpoint not claimed");
-    auto ret = TEMP_FAILURE_RETRY(write(m_writeEp, "#", 1));
-    RUNNER_ASSERT_ERRNO_MSG(ret > 0, "Write failed ret = " << ret);
+    post("#", 1);
 }
 
 void SynchronizationPipe::wait() {
+    char dummy;
+    wait(&dummy, 1);
+}
+
+void SynchronizationPipe::pollForWait() {
+    RUNNER_ASSERT_MSG(m_epClaimed == true, "Endpoint not claimed");
+
+    pollfd fds[1];
+    fds->fd = m_readEp;
+    fds->events = POLLIN;
+    auto ret = TEMP_FAILURE_RETRY(poll(fds, 1, -1));
+    RUNNER_ASSERT_ERRNO(ret > 0);
+}
+
+void SynchronizationPipe::post(const void *data, size_t size) {
+    RUNNER_ASSERT_MSG(m_epClaimed == true, "Endpoint not claimed");
+    auto ret = TEMP_FAILURE_RETRY(write(m_writeEp, data, size));
+    RUNNER_ASSERT_ERRNO_MSG(ret > 0 && size_t(ret) == size, "Write failed size = " << size << " ret = " << ret);
+}
+
+void SynchronizationPipe::wait(void *data, size_t size) {
     RUNNER_ASSERT_MSG(m_epClaimed == true, "Endpoint not claimed");
 
-    char buf;
-    auto ret = TEMP_FAILURE_RETRY(read(m_readEp, &buf, 1));
-    RUNNER_ASSERT_ERRNO_MSG(ret > 0, "Read failed ret = " << ret);
+    auto ret = TEMP_FAILURE_RETRY(read(m_readEp, data, size));
+    RUNNER_ASSERT_ERRNO_MSG(ret > 0 && size_t(ret) == size, "Read failed size = " << size << " ret = " << ret);
 }
index e072ca2..099323d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015-2020 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.
@@ -33,6 +33,10 @@ public:
 
     void post();
     void wait();
+    void pollForWait();
+
+    void post(const void *data, size_t size);
+    void wait(void *data, size_t size);
 
 private:
     int m_pipeCP[2];    // Child -> Parent
index 2eb4a00..bfb46d9 100644 (file)
@@ -38,7 +38,7 @@
 #include <string.h>
 
 const uid_t APP_UID     = 5001;
-const gid_t APP_GID     = 5001;
+const gid_t APP_GID     = 100;
 const uid_t APP_UID_2   = 5200;
 const gid_t APP_GID_2   = 5200;
 const uid_t DB_ALARM_UID = 6001;
index 57fc289..21c9460 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2020 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.
@@ -137,6 +137,9 @@ void Client::process(int expectedResult,
     tv.tv_sec = timeoutSeconds;
     tv.tv_usec = 0;
 
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wrestrict"
+
     int ret;
     if (m_statusMonitor.getStatus() == READ)
         ret = TEMP_FAILURE_RETRY(select(fd + 1, &fds, NULL, NULL, &tv));
@@ -149,6 +152,7 @@ void Client::process(int expectedResult,
                              << " ret = " << ret);
         return;
     }
+#pragma GCC diagnostic push
     RUNNER_ASSERT_ERRNO_MSG(ret > 0,
                                "Select returned error:"
                                << " ret = " << ret);
index 636a7cf..6adc2ef 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2011-2020 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.
@@ -58,7 +58,7 @@ void AssertProc(const char *condition,
         INTERNAL_LOG("### Function: " << function);
         INTERNAL_LOG(
             "################################################################################");
-    } catch (Exception) {
+    } catch (Exception&) {
         // Just ignore possible double errors
     }
 
index 8c91236..26a11d2 100644 (file)
@@ -274,6 +274,7 @@ void TestRunner::RunTestCase(TestCasePtr testCase)
             if (!testReason.empty())
                 testReason += "\n";
             testReason += finishReason;
+            break;
         case TestResult::FailStatus::NONE:
             if (!cleanupReason.empty()) {
                 if (!testReason.empty())
index 46e51d8..cf08aa4 100644 (file)
@@ -57,6 +57,7 @@ SET(SEC_MGR_SOURCES
     ${PROJECT_SOURCE_DIR}/src/security-manager-tests/security_manager_tests.cpp
     ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/policy_configuration.cpp
     ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_commons.cpp
+    ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/template_parser.cpp
     ${PROJECT_SOURCE_DIR}/src/cynara-tests/common/cynara_test_client.cpp
     ${PROJECT_SOURCE_DIR}/src/cynara-tests/common/cynara_test_admin.cpp
     ${PROJECT_SOURCE_DIR}/src/cynara-tests/plugins/plugins.cpp
index b8b389b..16db76c 100644 (file)
 #include <grp.h>
 #include <string>
 #include <sys/capability.h>
+#include <sys/prctl.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
 #include <unordered_map>
 #include <cstdlib>
 
+#include <array>
 #include <unordered_set>
+#include <utility>
 #include <vector>
 
 #include <security-manager-types.h>
 #include <policy_configuration.h>
 #include "tzplatform.h"
 #include <label_generator.h>
+#include <template_parser.h>
+#include <temp_test_user.h>
 
 using namespace SecurityManagerTest;
 
+#define CONF_DIR "/usr/share/security-manager/policy/"
+#define SMACK_RULES_PATH "/sys/fs/smackfs/load2"
+
+#define ALLOW 0
+#define DENY -1
+
 // Common DB/nftw checks
 
 // nftw doesn't allow passing user data to functions. Work around by using global variable
@@ -181,7 +192,75 @@ void sm_app_has_privileges(const AppInstallHelper &app,
     }
 }
 
-static void check_app(const std::string &appId, const std::string &pkgId, bool shouldBeInstalled)
+static void check_app_smack_accesses(const std::string &appId, const std::string &pkgId,
+                                     bool isHybrid = false)
+{
+    static const std::vector<AccessRequest> rules[] =
+        {parseSmackRulesFile(CONF_DIR "pkg-rules-template.smack"),
+         parseSmackRulesFile(CONF_DIR "app-rules-template.smack")};
+
+    const std::pair<std::string, std::string> switchAliases[] =
+        {std::make_pair("~PATH_RW~", generatePathRWLabel(pkgId)),
+         std::make_pair("~PATH_RO~", generatePathROLabel(pkgId)),
+         std::make_pair("~PATH_SHARED_RO~", getSharedROPathLabel()),
+         std::make_pair("~PROCESS~", generateProcessLabel(appId, pkgId, isHybrid))};
+
+    for (auto rule : rules[isHybrid]) {
+        if (rule.object == "~PATH_TRUSTED~") {
+            continue;
+        }
+
+        for (const auto &alias : switchAliases) {
+            if (rule.subject == alias.first) {
+                rule.subject = alias.second;
+            }
+            if (rule.object == alias.first) {
+                rule.object = alias.second;
+            }
+        }
+
+        if (rule.object == "_") {
+            rule.access = "rx" + rule.access;
+        }
+
+        check_exact_smack_accesses(rule.subject, rule.object, rule.access);
+    }
+}
+
+static void assert_no_label_in_rule(const AccessRequest &rule, const std::string &label)
+{
+    RUNNER_ASSERT_MSG(rule.object != label && rule.subject != label,
+                      "Smack rule left after uninstallation process." <<
+                      " Subject: " << rule.subject <<
+                      " object: " << rule.object <<
+                      " access: " << rule.access);
+}
+
+static void check_pkg_smack_rules_after_uninstall(const std::string &appId, const std::string &pkgId)
+{
+    const std::vector<AccessRequest> rules(std::move(parseSmackRulesFile(SMACK_RULES_PATH)));
+    const std::string labels[] = {generatePathRWLabel(pkgId),
+                                  generatePathROLabel(pkgId),
+                                  generateProcessLabel(appId, pkgId, true),
+                                  generateProcessLabel(appId, pkgId)};
+    for (const auto &rule : rules) {
+        for (const auto &label : labels) {
+            assert_no_label_in_rule(rule, label);
+        }
+    }
+}
+
+static void check_hybrid_app_smack_rules_after_uninstall(const std::string &appId, const std::string &pkgId)
+{
+    const std::vector<AccessRequest> rules(std::move(parseSmackRulesFile(SMACK_RULES_PATH)));
+    const std::string appLabel = generateProcessLabel(appId, pkgId, true);
+    for (const auto &rule : rules) {
+        assert_no_label_in_rule(rule, appLabel);
+    }
+}
+
+static void check_app(const std::string &appId, const std::string &pkgId,
+                      bool shouldBeInstalled, bool isHybrid, bool removePkg)
 {
     char *retPkgId;
     int ret = security_manager_get_app_pkgid(&retPkgId, appId.c_str());
@@ -194,14 +273,21 @@ static void check_app(const std::string &appId, const std::string &pkgId, bool s
             RUNNER_ASSERT_MSG(strcmp(pkgId.c_str(), retPkgId) == 0,
                               "The given appId does not belong to the given pkgId.");
         }
+        check_app_smack_accesses(appId, pkgId, isHybrid);
     } else {
         RUNNER_ASSERT_MSG(ret == SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT, "The given appId is installed.");
+
+        if (removePkg) {
+            check_pkg_smack_rules_after_uninstall(appId, pkgId);
+        } else if (isHybrid) {
+            check_hybrid_app_smack_rules_after_uninstall(appId, pkgId);
+        }
     }
 }
 
-void check_app_after_install(const std::string &app_id, const std::string &pkg_id)
+void check_app_after_install(const std::string &app_id, const std::string &pkg_id, bool isHybrid)
 {
-    check_app(app_id, pkg_id, true);
+    check_app(app_id, pkg_id, true, isHybrid, false);
 }
 
 static void check_app_gids(const std::string &app_id, const std::vector<gid_t> &allowed_gids)
@@ -239,8 +325,7 @@ void check_app_after_install(const std::string &app_id, const std::string &pkg_i
                              const privileges_t &denied_privs,
                              bool isHybrid)
 {
-    check_app(app_id, pkg_id, true);
-
+    check_app(app_id, pkg_id, true, isHybrid, false);
     /* Privileges should be granted to all users if root installs app */
     check_app_permissions(app_id, pkg_id, ANY_USER_REPRESENTATION, allowed_privs, denied_privs, isHybrid);
 
@@ -270,15 +355,17 @@ void check_path(const std::string &path, const std::string &label, bool transmut
     RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << path);
 }
 
-void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id)
+void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id,
+                               bool isHybrid, bool removePkg)
 {
-    check_app(app_id, pkg_id, false);
+    check_app(app_id, pkg_id, false, isHybrid, removePkg);
 }
 
 void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id,
-                               const privileges_t &privileges, bool isHybrid)
+                               const privileges_t &privileges, bool isHybrid,
+                               bool removePkg)
 {
-    check_app(app_id, pkg_id, false);
+    check_app(app_id, pkg_id, false, isHybrid, removePkg);
 
     /* Privileges should not be granted anymore to any user */
     check_app_permissions(app_id, pkg_id, ANY_USER_REPRESENTATION, {}, privileges, isHybrid);
@@ -355,22 +442,30 @@ void accessCheck(const std::string &id, const std::string &path, int accessType,
                        << " (" << accessTypeToString.at(accessType) << ")");
 }
 
+void accessTest(const std::string &id, const std::string &testPath, int accessType) {
+    int oppositeAccessType = getOppositeAccessType(accessType);
+
+    if (accessType != 0) {
+        accessCheck(id, testPath, accessType, ALLOW);
+    }
+    if (oppositeAccessType != 0) {
+        static const std::vector<int> singleAccessTypes = {R_OK, W_OK, X_OK};
+        for (auto singleAccessType : singleAccessTypes) {
+            if (oppositeAccessType & singleAccessType) {
+                accessCheck(id, testPath, singleAccessType, DENY);
+            }
+        }
+    }
+}
+
 void runAccessTest(const std::string &label, uid_t uid, gid_t gid,
                    const std::string &testPath, int accessType) {
     auto fun = [&](){
-        int oppositeAccessType = getOppositeAccessType(accessType);
         ScopedProcessLabel spl(label, false);
         RUNNER_ASSERT_ERRNO_MSG(0 == drop_root_privileges(uid, gid),
                                 "drop_root_privileges failed.");
 
-        if (accessType != 0)
-            accessCheck(label, testPath, accessType, 0);
-        if (oppositeAccessType != 0) {
-            std::vector<int> singleAccessTypes = {R_OK, W_OK, X_OK};
-            for (auto singleAccessType : singleAccessTypes)
-                if (oppositeAccessType & singleAccessType)
-                    accessCheck(label, testPath, singleAccessType, -1);
-        }
+        accessTest(label, testPath, accessType);
     };
 
     runInChildParentWait(fun);
@@ -378,18 +473,10 @@ void runAccessTest(const std::string &label, uid_t uid, gid_t gid,
 
 void runAccessTest(const AppInstallHelper &app, const std::string &testPath, int accessType) {
     auto fun = [&](){
-        int oppositeAccessType = getOppositeAccessType(accessType);
         Api::setProcessLabel(app.getAppId());
         RUNNER_ASSERT_ERRNO_MSG(0 == drop_root_privileges(app.getUID(), app.getGID()),
                                 "drop_root_privileges failed.");
-        if (accessType != 0)
-            accessCheck(app.getAppId(), testPath, accessType, 0);
-        if (oppositeAccessType != 0) {
-            std::vector<int> singleAccessTypes = {R_OK, W_OK, X_OK};
-            for (auto singleAccessType : singleAccessTypes)
-                if (oppositeAccessType & singleAccessType)
-                    accessCheck(app.getAppId(), testPath, singleAccessType, -1);
-        }
+        accessTest(app.getAppId(), testPath, accessType);
     };
 
     runInChildParentWait(fun);
@@ -429,3 +516,29 @@ int countPrivacyPrivileges(const std::vector<std::string> &privs) {
     return std::count_if(privs.begin(), privs.end(), isPrivilegePrivacy);
 }
 
+int setLauncherSecurityAttributes(uid_t uid, gid_t gid)
+{
+    // Add launcher capabilities (cap_dac_override, cap_setgid, cap_sys_admin, cap_mac_admin),
+    // launcher is user process, we must drop root privileges (cap_setgid, cap_setuid are needed).
+    // By default, the permitted capability set is cleared when credentials change is made
+    // (if a process drops a capability from its permitted set, it can never reacquire that capability),
+    // setting the "keep capabilities" flag prevents it from being cleared.
+    // Effective capability set is always cleared when credential change is made, we need to add them again.
+
+    setCaps("cap_dac_override+ep cap_setgid+ep cap_sys_admin+ep cap_mac_admin+ep cap_setuid+ep");
+    int ret = prctl(PR_SET_KEEPCAPS, 1, 0, 0);
+    if (ret != 0)
+        return ret;
+
+    ret = drop_root_privileges(uid, gid);
+    if (ret != 0)
+        return ret;
+
+    setCaps("cap_dac_override+ep cap_setgid+ep cap_sys_admin+ep cap_mac_admin+ep");
+    return ret;
+}
+int setLauncherSecurityAttributes(TemporaryTestUser &user)
+{
+    return setLauncherSecurityAttributes(user.getUid(), user.getGid());
+}
+
index 902d70c..6840281 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2016-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.
@@ -45,17 +45,19 @@ void check_app_permissions(const std::string &app_id, const std::string &pkg_id,
 void sm_app_has_privileges(const AppInstallHelper &app,
                            const std::vector<std::string> &privileges,
                            int result);
-void check_app_after_install(const std::string &app_id, const std::string &pkg_id);
+void check_app_after_install(const std::string &app_id, const std::string &pkg_id,
+                             bool isHybrid = false);
 void check_app_after_install(const std::string &app_id, const std::string &pkg_id,
                              const privileges_t &allowed_privs,
                              const privileges_t &denied_privs,
                              bool isHybrid = false);
 void check_path(const std::string &path, const std::string &label,
                 bool transmute = true, bool execute = false);
-void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id);
 void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id,
-                               const privileges_t &privileges, bool isHybrid = false);
-
+                               bool isHybrid = false, bool removePkg = false);
+void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id,
+                               const privileges_t &privileges, bool isHybrid = false,
+                               bool removePkg = false);
 std::string access_opposite(std::string &access);
 void check_exact_smack_accesses(const std::string &subject,
                                 const std::string &object,
@@ -63,6 +65,7 @@ void check_exact_smack_accesses(const std::string &subject,
 
 CapsSetsUniquePtr setCaps(const char *cap_string);
 
+void accessTest(const std::string &id, const std::string &testPath, int accessType);
 void runAccessTest(const std::string &label, uid_t uid, gid_t gid,
                    const std::string &testPath, int accessType);
 void runAccessTest(const AppInstallHelper &app, const std::string &testPath, int accessType);
@@ -72,3 +75,6 @@ bool isAskuserDisabled();
 bool isPrivilegePrivacy(const std::string &priv);
 int countPrivacyPrivileges(const PrivilegeVector &privs);
 int countPrivacyPrivileges(const std::vector<std::string> &privs);
+
+int setLauncherSecurityAttributes(uid_t uid, gid_t gid);
+int setLauncherSecurityAttributes(TemporaryTestUser &user);
diff --git a/src/security-manager-tests/common/template_parser.cpp b/src/security-manager-tests/common/template_parser.cpp
new file mode 100644 (file)
index 0000000..83c5b46
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 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.
+ *    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        template_parser.cpp
+ * @author      Alicja Kluczek <a.kluczek@samsung.com>
+ * @brief       Parsing function for smack rules templates
+ */
+#include "template_parser.h"
+#include <fstream>
+
+std::vector<AccessRequest> parseSmackRulesFile(const std::string &path)
+{
+    std::vector<AccessRequest> rules;
+    std::ifstream rulesFile(path);
+    std::string object, subject, access;
+    while (rulesFile >> subject >> object >> access) {
+        rules.emplace_back(std::move(subject), std::move(object), std::move(access));
+    }
+    return rules;
+}
+
diff --git a/src/security-manager-tests/common/template_parser.h b/src/security-manager-tests/common/template_parser.h
new file mode 100644 (file)
index 0000000..81a3674
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 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.
+ *    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        template_parser.h
+ * @author      Alicja Kluczek <a.kluczek@samsung.com>
+ * @brief       Parsing function for smack rules templates
+ */
+#include <vector>
+#include <string>
+
+struct AccessRequest {
+    AccessRequest(std::string sub, std::string obj, std::string acc)
+    : subject(std::move(sub)),
+      object(std::move(obj)),
+      access(std::move(acc))
+    {}
+    std::string subject;
+    std::string object;
+    std::string access;
+};
+
+std::vector<AccessRequest> parseSmackRulesFile(const std::string &path);
+
index 5bde91d..8b7a7fc 100644 (file)
@@ -139,7 +139,7 @@ RUNNER_TEST(security_manager_01d_app_install_complicated_dir_tree)
     check_path(privateDir, generatePathRWLabel(pkgId));
     check_path(privateRODir, generatePathROLabel(pkgId), false);
     check_path(publicRODir, getPublicPathLabel());
-    check_path(sharedRODir, generatePathSharedROLabel(pkgId));
+    check_path(sharedRODir, getSharedROPathLabel());
 }
 
 RUNNER_TEST(security_manager_02_app_install_uninstall_full)
@@ -176,7 +176,7 @@ RUNNER_TEST(security_manager_02_app_install_uninstall_full)
         check_path(app.getPrivateDir(), generatePathRWLabel(app.getPkgId()));
         check_path(app.getPrivateRODir(), generatePathROLabel(app.getPkgId()), false);
         check_path(app.getPublicDir(), getPublicPathLabel());
-        check_path(app.getSharedRODir(), generatePathSharedROLabel(app.getPkgId()));
+        check_path(app.getSharedRODir(), getSharedROPathLabel());
     }
 
     check_app_after_uninstall(app.getAppId(), app.getPkgId(), app.getPrivilegesNames());
@@ -508,6 +508,98 @@ RUNNER_TEST(security_manager_09_app_install_constraint_check)
     install(users[0], pkgId[0], appId[0], version[0], author[1], hybrid[0], SECURITY_MANAGER_ERROR_INPUT_PARAM);
 }
 
+RUNNER_TEST(security_manager_09a_install_many_apps_in_single_request)
+{
+    const std::string pkgId = "sm_test_09a_pkg_id_0";
+    const std::vector<std::string> appIds = {"sm_test_09a_app_id_0", "sm_test_09a_app_id_1", "sm_test_09a_app_id_2"};
+
+    {
+        ScopedInstaller appsInstall(appIds, pkgId);
+        // Installing many applications in single request
+        for (const auto &appId : appIds) {
+            check_app_after_install(appId, pkgId);
+        }
+    }
+
+    for (const auto &appId : appIds) {
+        check_app_after_uninstall(appId, pkgId);
+    }
+}
+
+RUNNER_TEST(security_manager_09b_install_many_apps_in_single_request_duplicated_ids)
+{
+    const std::string pkgId = "sm_test_09b_pkg_id_0";
+    const std::string appId = "sm_test_09b_app_id_0";
+
+    {
+        ScopedInstaller appsInstall({appId, appId}, pkgId);
+        check_app_after_install(appId, pkgId);
+    }
+
+    check_app_after_uninstall(appId, pkgId);
+}
+
+RUNNER_TEST(security_manager_09c_update_many_apps_in_single_request_hybrid_package)
+{
+    const std::vector<std::string> appIds = {"sm_test_09c_app_id_0", "sm_test_09c_app_id_1", "sm_test_09c_app_id_2"};
+    const std::string pkgId = "sm_test_09c_pkg_id_0";
+
+    {
+        ScopedInstaller appsInstall(appIds, pkgId);
+        // Package is not hybrid, every app has same policy.
+        for (const auto &appId : appIds) {
+            check_app_after_install(appId, pkgId);
+        }
+
+        // Updating package -- changing set of apps in package and setting hybrid mode
+        InstallRequest updateRequest;
+        updateRequest.setPkgId(pkgId);
+        updateRequest.setAppId(appIds[0]);
+        updateRequest.nextApp();
+        updateRequest.setAppId(appIds[1]);
+        updateRequest.setHybrid();
+
+        Api::update(updateRequest);
+        // Package became hybrid, so every app has its own Smack label
+        check_app_after_install(appIds[0], pkgId, true);
+        check_app_after_install(appIds[1], pkgId, true);
+        // Package became hybrid properly,
+        // so app not included in updated version of package was uninstalled.
+        check_app_after_uninstall(appIds[2], pkgId);
+    }
+
+    for (const auto &appId : appIds) {
+        check_app_after_uninstall(appId, pkgId, true, true);
+    }
+}
+
+RUNNER_TEST(security_manager_09d_uninstall_app_from_hybrid_package)
+{
+    const std::vector<std::string> appIds = {"sm_test_09d_app_id_0", "sm_test_09d_app_id_1", "sm_test_09d_app_id_2"};
+    const std::string pkgId = "sm_test_09d_pkg_id_0";
+    {
+        ScopedInstaller appsInstall(appIds, pkgId);
+
+        InstallRequest updateRequest;
+        updateRequest.setPkgId(pkgId);
+        for (unsigned int i = 0; i < appIds.size(); i++) {
+            if (i > 0) {
+                updateRequest.nextApp();
+            }
+            updateRequest.setAppId(appIds[i]);
+        }
+        updateRequest.setHybrid();
+        Api::update(updateRequest);
+
+        InstallRequest uninstRequest;
+        uninstRequest.setPkgId(pkgId);
+        uninstRequest.setAppId(appIds[0]);
+        Api::uninstall(uninstRequest);
+
+        check_app_after_uninstall(appIds[0], pkgId, true);
+    }
+}
+
 RUNNER_CHILD_TEST(security_manager_10_app_has_privilege)
 {
     const std::vector<std::string> allowedPrivs = {
index 79f75ad..9ff9179 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2016-2020 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.
  *    limitations under the License.
  */
 
+#include <poll.h>
 #include <sys/smack.h>
 #include <sys/capability.h>
 #include <sys/prctl.h>
+#include <sys/eventfd.h>
 
+#include <cmath>
 #include <thread>
 #include <string>
 #include <memory>
@@ -118,28 +121,6 @@ struct ThreadWrapper
     std::thread thread;
 };
 
-int setLauncherSecurityAttributes(TemporaryTestUser &user)
-{
-    // Add launcher capabilities (cap_dac_override, cap_setgid, cap_sys_admin, cap_mac_admin),
-    // launcher is user process, we must drop root privileges (cap_setgid, cap_setuid are needed).
-    // By default, the permitted capability set is cleared when credentials change is made
-    // (if a process drops a capability from its permitted set, it can never reacquire that capability),
-    // setting the "keep capabilities" flag prevents it from being cleared.
-    // Effective capability set is always cleared when credential change is made, we need to add them again.
-
-    setCaps("cap_dac_override+ep cap_setgid+ep cap_sys_admin+ep cap_mac_admin+ep cap_setuid+ep");
-    int ret = prctl(PR_SET_KEEPCAPS, 1, 0, 0);
-    if (ret != 0)
-        return ret;
-
-    ret = drop_root_privileges(user.getUid(), user.getGid());
-    if (ret != 0)
-        return ret;
-
-    setCaps("cap_dac_override+ep cap_setgid+ep cap_sys_admin+ep cap_mac_admin+ep");
-    return ret;
-}
-
 ino_t getFileInode(const std::string &path)
 {
     struct stat st;
@@ -186,7 +167,7 @@ RUNNER_CHILD_TEST(security_manager_100_synchronize_credentials_test)
     if (pid == 0) {
         {
             RUNNER_ASSERT_ERRNO_MSG(setLauncherSecurityAttributes(tmpUser) == 0, "launcher failed");
-
+            Api::prepareAppCandidate();
             ThreadWrapper threads[THREADS];
 
             for (size_t i = 0; i < THREADS; i++)
@@ -202,6 +183,34 @@ RUNNER_CHILD_TEST(security_manager_100_synchronize_credentials_test)
     }
 }
 
+RUNNER_CHILD_TEST(security_manager_101_create_namespace_test_n)
+{
+    TemporaryTestUser tmpUser(APP_TEST_USER, GUM_USERTYPE_NORMAL, false);
+    tmpUser.create();
+
+    AppInstallHelper app("app100_n", tmpUser.getUid());
+    ScopedInstaller appInstall(app);
+    const std::string expectedLabel = app.generateAppLabel();
+
+    pid_t pid = fork();
+    RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "Fork failed");
+    if (pid == 0) {
+        {
+            RUNNER_ASSERT_ERRNO_MSG(setLauncherSecurityAttributes(tmpUser) == 0, "launcher failed");
+            ThreadWrapper threads[THREADS];
+
+            for (size_t i = 0; i < THREADS; i++)
+                threads[i].run(i, expectedLabel);
+
+            Api::prepareAppCandidate(SECURITY_MANAGER_ERROR_INPUT_PARAM);
+        }
+        RUNNER_ASSERT_MSG(!thread_errors.empty(), std::endl << thread_errors);
+        exit(0);
+    } else {
+        waitPid(pid);
+    }
+}
+
 RUNNER_CHILD_TEST(security_manager_101_create_namespace_test)
 {
     TemporaryTestUser tmpUser(APP_TEST_USER, GUM_USERTYPE_NORMAL, false);
@@ -216,7 +225,7 @@ RUNNER_CHILD_TEST(security_manager_101_create_namespace_test)
     if (pid == 0) {
         synchPipe.claimParentEp();
         RUNNER_ASSERT_ERRNO_MSG(setLauncherSecurityAttributes(tmpUser) == 0, "launcher failed");
-
+        Api::prepareAppCandidate();
         Api::prepareApp(app.getAppId().c_str());
         synchPipe.post();
         synchPipe.wait();
@@ -262,7 +271,7 @@ RUNNER_CHILD_TEST(security_manager_102_check_propagation_test)
     if (pid == 0) {
         synchPipe.claimParentEp();
         RUNNER_ASSERT_ERRNO_MSG(setLauncherSecurityAttributes(tmpUser) == 0, "launcher failed");
-
+        Api::prepareAppCandidate();
         Api::prepareApp(app.getAppId().c_str());
         synchPipe.post();
         synchPipe.wait();
@@ -308,7 +317,7 @@ RUNNER_CHILD_TEST(security_manager_103_policy_change_test)
     if (pid == 0) {
         synchPipe.claimParentEp();
         RUNNER_ASSERT_ERRNO_MSG(setLauncherSecurityAttributes(tmpUser) == 0, "launcher failed");
-
+        Api::prepareAppCandidate();
         Api::prepareApp(app.getAppId().c_str());
         synchPipe.post();
         synchPipe.wait();
@@ -363,3 +372,194 @@ RUNNER_CHILD_TEST(security_manager_103_policy_change_test)
         Api::cleanupApp(app.getAppId().c_str(), tmpUser.getUid(), pid);
     }
 }
+
+namespace {
+class Timestamp {
+    uint64_t _;
+    explicit Timestamp(uint64_t ts) : _(ts) {}
+public:
+    Timestamp operator-(const Timestamp &other) const {
+        RUNNER_ASSERT(_ > other._);
+        return Timestamp(_ - other._);
+    }
+    Timestamp operator+(const Timestamp &other) const {
+        return Timestamp(_ + other._);
+    }
+    bool operator<(const Timestamp &other) const {
+        return _ < other._;
+    }
+    Timestamp() = default;
+    static Timestamp future(uint64_t ns) {
+        timespec ts;
+        const auto res = clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
+        RUNNER_ASSERT_ERRNO(!res);
+        return Timestamp(ts.tv_sec * 1000000000ULL + ts.tv_nsec + ns);
+    }
+    static Timestamp now() {
+        return future(0);
+    }
+    template <size_t nLowDigitsToSkip = 3>
+    static void report(Timestamp *ts, size_t n) {
+        std::sort(ts, ts+n);
+        uint64_t sum = 0, mn = -1, mx = 0;
+        long double qsum = 0;
+        for (size_t i = 0; i < n; i++) {
+            const auto t = ts[i]._;
+            sum += t;
+            qsum += decltype(qsum)(t) * t;
+            mn = std::min(mn, t);
+            mx = std::max(mx, t);
+        }
+        uint64_t avg = sum / n;
+        auto qstddev = qsum/n - decltype(qsum)(avg)*avg;
+        const auto out = [](const char *desc, uint64_t t) {
+            char raw[20];
+        char s[20 + 20/3 + 1];
+        size_t j = 0, i = 0;
+        do
+            raw[j++] = '0' + t % 10ULL;
+        while (t /= 10ULL);
+        for (;;) {
+            s[i++] = raw[--j];
+            if (j <= nLowDigitsToSkip)
+                break;
+            if (!(j % 3))
+                s[i++] = ' ';
+        }
+        s[i] = '\0';
+        std::cerr << desc << s;
+    };
+    out("min ", mn);
+    out(" max ", mx);
+    out(" avg ", avg);
+    out(" median ", ts[n/2]._);
+    out(" stddev ", std::floor(std::sqrt(qstddev)));
+    std::cerr << '\n';
+    }
+};
+
+template <class T, size_t N>
+constexpr size_t arraySize(T (&)[N]) { return N; }
+} // namespace
+
+RUNNER_TEST(security_manager_200_prepare_app_perf)
+{
+    constexpr int8_t nThreads = 32;
+    constexpr int8_t nConcurrentAppsSamples[] = { 0 /* 1 app w/ nThreads */, 1, 2, 4, 8, 16, 32 };
+    constexpr uint64_t minTotalBenchTime = 60 * 1000ULL*1000*1000; // 60s
+
+    TemporaryTestUser tmpUser(APP_TEST_USER, GUM_USERTYPE_NORMAL, false);
+    tmpUser.create();
+
+    struct App {
+        AppInstallHelper hlp;
+        pid_t pid;
+    };
+
+    std::vector<Timestamp> candidate, prepare, everything;
+
+    std::vector<App> apps;
+    std::vector<ScopedInstaller> appInstalls;
+
+    constexpr auto nAppsMax = nConcurrentAppsSamples[arraySize(nConcurrentAppsSamples) - 1] ?: 1;
+    apps.reserve(nAppsMax);
+    appInstalls.reserve(nAppsMax);
+
+    const auto uid = tmpUser.getUid();
+    for (int i = 0; i < nAppsMax; i++) {
+        apps.emplace_back(App{AppInstallHelper("app200_" + std::to_string(i), uid), 0});
+        auto &hlp = apps.back().hlp;
+        for (const auto &p : { EXTERNAL_STORAGE_PRIVILEGE, MEDIA_STORAGE_PRIVILEGE,
+                std::string("http://tizen.org/privilege/camera"),
+                std::string("http://tizen.org/privilege/internet") })
+            hlp.addPrivilege(p);
+        hlp.createSharedRODir();
+        appInstalls.emplace_back(ScopedInstaller(hlp));
+    }
+
+    for (const auto nConcurrentAppsDesc : nConcurrentAppsSamples) {
+        const auto nConcurrentApps = nConcurrentAppsDesc ?: 1;
+        const auto timeout = Timestamp::future(minTotalBenchTime / arraySize(nConcurrentAppsSamples));
+        do {
+            SynchronizationPipe synchPipe;
+            auto exitEvFd = eventfd(0, 0);
+            RUNNER_ASSERT(exitEvFd >= 0);
+
+            for (int i = 0; i < nConcurrentApps; i++) {
+                auto &app = apps[i];
+                const auto pid = fork();
+                RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "Fork failed");
+                if (pid)
+                    app.pid = pid;
+                else {
+                    synchPipe.claimChildEp();
+                    RUNNER_ASSERT_ERRNO_MSG(setLauncherSecurityAttributes(tmpUser) == 0, "launcher failed");
+
+                    const auto appId = app.hlp.getAppId();
+
+                    synchPipe.post(); // declare readiness to start measuring
+                    synchPipe.pollForWait(); // wait for parent to signal all kids simultaneously
+
+                    const auto candBeg = Timestamp::now();
+                    Api::prepareAppCandidate();
+                    const auto candEnd = Timestamp::now();
+
+                    if (!nConcurrentAppsDesc) {
+                        for (int i = 0; i < nThreads; i++)
+                            std::thread([]{ for (;;) usleep(1000); }).detach();
+                    }
+
+                    const auto prepBeg = Timestamp::now();
+                    Api::prepareApp(appId);
+                    const auto prepEnd = Timestamp::now();
+
+                    const Timestamp ts[2] = { candEnd-candBeg, prepEnd-prepBeg };
+                    synchPipe.post(ts, sizeof ts); // post measurement payload
+
+                    // stay idle until all kids are done to simulate idle apps and reduce benchmark noise
+                    pollfd fds[1];
+                    fds->fd = exitEvFd;
+                    fds->events = POLLIN;
+                    auto ret = TEMP_FAILURE_RETRY(poll(fds, 1, -1));
+                    RUNNER_ASSERT_ERRNO(ret > 0);
+
+                    exit(0);
+                }
+            }
+            synchPipe.claimParentEp();
+
+            for (int i = 0; i < nConcurrentApps; i++) // wait for all kids to be ready to start measurement
+                synchPipe.wait();
+            synchPipe.post(); // signal all kids to start measuring
+
+            for (int i = 0; i < nConcurrentApps; i++) {
+                Timestamp ts[2];
+                synchPipe.wait(ts, sizeof ts);
+                candidate.emplace_back(ts[0]);
+                prepare.emplace_back(ts[1]);
+                everything.emplace_back(ts[0] + ts[1]);
+            }
+
+            RUNNER_ASSERT(!eventfd_write(exitEvFd, 1)); // signal all kids to exit now
+
+            for (int i = 0; i < nConcurrentApps; i++) {
+                const auto &app = apps[i];
+                waitPid(app.pid);
+                Api::cleanupApp(app.hlp.getAppId(), uid, app.pid);
+            }
+        } while (Timestamp::now() < timeout);
+
+        if (!nConcurrentAppsDesc)
+            std::cerr << "additionalThreads " << int(nThreads) << ' ';
+        std::cerr << "nConcurrentApps " << int(nConcurrentApps) << " samples " << candidate.size() << '\n';
+        std::cerr << "  prepareAppCandidate [us]:              ";
+        Timestamp::report(candidate.data(), candidate.size());
+        std::cerr << "  prepareApp [us]:                       ";
+        Timestamp::report(prepare.data(), prepare.size());
+        std::cerr << "  prepareAppCandidate + prepareApp [us]: ";
+        Timestamp::report(everything.data(), everything.size());
+        candidate.clear();
+        prepare.clear();
+        everything.clear();
+    }
+}
index d882c0f..b71ad04 100644 (file)
@@ -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
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -15,6 +15,7 @@
  */
 #include <cstdint>
 #include <fcntl.h>
+#include <functional>
 #include <unordered_map>
 #include <string>
 #include <sys/smack.h>
@@ -32,6 +33,7 @@ using namespace SecurityManagerTest;
 namespace {
 
 const uid_t OWNER_UID = 5001;
+const uid_t OWNER_GID = 100;
 
 const std::vector<std::string> versions = {
         "2.4",
@@ -54,6 +56,25 @@ const VersionCombinations versionCombinations = makeVersionCombinations(versions
 
 RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_SHARED_RO)
 
+static void runAccessTest(uid_t uid, gid_t gid, const std::string &appId,
+                          std::function<void(void)> f)
+{
+    pid_t pid = fork();
+
+    RUNNER_ASSERT_ERRNO_MSG(pid >= 0, "Fork failed");
+    if (pid == 0) {
+        setLauncherSecurityAttributes(uid, gid);
+        Api::prepareAppCandidate();
+        Api::prepareApp(appId.c_str());
+        f();
+        exit(0);
+    } else {
+
+        waitPid(pid);
+        Api::cleanupApp(appId.c_str(), uid, pid);
+    }
+}
+
 /**
  * Check whether owner app have access to own sharedRO dir
  */
@@ -64,10 +85,29 @@ RUNNER_CHILD_TEST(security_manager_76_owner_access)
         app.createSharedRODir();
         ScopedInstaller sharedROPkgApp(app);
 
-        runAccessTest(app, app.getSharedRODir(), R_OK|W_OK|X_OK);
+        runAccessTest(OWNER_UID, OWNER_GID, app.getAppId(), [&]() {
+            accessTest(app.getAppId(), app.getSharedRODir(), R_OK|W_OK|X_OK);
+        });
     }
 }
 
+RUNNER_CHILD_TEST(security_manager_7x_test)
+{
+    AppInstallHelper ownerApp("owner_7x", OWNER_UID);
+    ownerApp.createSharedRODir();
+    ScopedInstaller ownerAppInstall(ownerApp);
+
+    AppInstallHelper otherApp("other_7x", OWNER_UID);
+    otherApp.createSharedRODir();
+    ScopedInstaller otherAppInstall(otherApp);
+
+    runAccessTest(OWNER_UID, OWNER_GID, ownerApp.getAppId(), [&]() {
+        accessTest(ownerApp.getAppId(), ownerApp.getSharedRODir(), R_OK | W_OK | X_OK);
+        accessTest(ownerApp.getAppId(), otherApp.getSharedRODir(), R_OK | X_OK);
+        exit(0);
+    });
+}
+
 /**
  * Check whether app without shared RO path has access to shared RO dir and
  * no access to private directories of application from different package between
@@ -84,9 +124,14 @@ RUNNER_CHILD_TEST(security_manager_77_owner_other_access_version_combinations)
         AppInstallHelper nonSharedApp("sm_test_77_nonshared", OWNER_UID, version.second);
         ScopedInstaller nonSharedAppInstall(nonSharedApp);
 
-        runAccessTest(sharedApp, sharedApp.getSharedRODir(), R_OK|W_OK|X_OK);
-        runAccessTest(nonSharedApp, sharedApp.getPrivateDir(), 0);
-        runAccessTest(nonSharedApp, sharedApp.getSharedRODir(), R_OK|X_OK);
+        runAccessTest(OWNER_UID, OWNER_GID, sharedApp.getAppId(), [&]() {
+            accessTest(sharedApp.getAppId(), sharedApp.getSharedRODir(), R_OK|W_OK|X_OK);
+        });
+
+        runAccessTest(OWNER_UID, OWNER_GID, nonSharedApp.getAppId(), [&]() {
+            accessTest(nonSharedApp.getAppId(), sharedApp.getPrivateDir(), 0);
+            accessTest(nonSharedApp.getAppId(), sharedApp.getSharedRODir(), R_OK|X_OK);
+        });
     }
 }
 
@@ -108,12 +153,17 @@ RUNNER_CHILD_TEST(security_manager_78_another_pkg_shared_ro_have_ro_access_to_sh
         sharedApp2.createPrivateDir();
         ScopedInstaller sharedApp2Install(sharedApp2);
 
-        runAccessTest(sharedApp2, sharedApp1.getSharedRODir(), R_OK|X_OK);
-        runAccessTest(sharedApp1, sharedApp2.getSharedRODir(), R_OK|X_OK);
-        runAccessTest(sharedApp1, sharedApp1.getSharedRODir(), R_OK|W_OK|X_OK);
-        runAccessTest(sharedApp2, sharedApp2.getSharedRODir(), R_OK|W_OK|X_OK);
-        runAccessTest(sharedApp2, sharedApp1.getPrivateDir(), 0);
-        runAccessTest(sharedApp1, sharedApp2.getPrivateDir(), 0);
+        runAccessTest(OWNER_UID, OWNER_GID, sharedApp1.getAppId(), [&]() {
+            accessTest(sharedApp1.getAppId(), sharedApp2.getSharedRODir(), R_OK|X_OK);
+            accessTest(sharedApp1.getAppId(), sharedApp1.getSharedRODir(), R_OK|W_OK|X_OK);
+            accessTest(sharedApp1.getAppId(), sharedApp2.getPrivateDir(), 0);
+        });
+
+        runAccessTest(OWNER_UID, OWNER_GID, sharedApp2.getAppId(), [&]() {
+            accessTest(sharedApp2.getAppId(), sharedApp1.getSharedRODir(), R_OK|X_OK);
+            accessTest(sharedApp2.getAppId(), sharedApp2.getSharedRODir(), R_OK|W_OK|X_OK);
+            accessTest(sharedApp2.getAppId(), sharedApp1.getPrivateDir(), 0);
+        });
     }
 }
 
@@ -134,9 +184,13 @@ RUNNER_CHILD_TEST(security_manager_79a_same_pkg_shared_ro_have_ro_access_to_shar
         sharedApp2.createSharedRODir();
         ScopedInstaller sharedAppInstall2(sharedApp2);
 
-        runAccessTest(sharedApp2, sharedApp1.getSharedRODir(), R_OK|W_OK|X_OK);
-        runAccessTest(sharedApp1, sharedApp2.getSharedRODir(), R_OK|W_OK|X_OK);
-    };
+        runAccessTest(OWNER_UID, OWNER_GID, sharedApp1.getAppId(), [&]() {
+            accessTest(sharedApp1.getAppId(), sharedApp2.getSharedRODir(), R_OK|W_OK|X_OK);
+        });
+        runAccessTest(OWNER_UID, OWNER_GID, sharedApp2.getAppId(), [&]() {
+            accessTest(sharedApp2.getAppId(), sharedApp1.getSharedRODir(), R_OK|W_OK|X_OK);
+        });
+    }
 }
 
 /**
@@ -155,7 +209,9 @@ RUNNER_CHILD_TEST(security_manager_79b_same_pkg_shared_ro_have_ro_access_to_shar
         AppInstallHelper nonSharedApp("sm_test_79b_shared2", sharedPkgName, OWNER_UID, version);
         ScopedInstaller nonSharedAppInstall(nonSharedApp);
 
-        runAccessTest(nonSharedApp, sharedApp.getSharedRODir(), R_OK|W_OK|X_OK);
+        runAccessTest(OWNER_UID, OWNER_GID, nonSharedApp.getAppId(), [&]() {
+            accessTest(nonSharedApp.getAppId(), sharedApp.getSharedRODir(), R_OK|W_OK|X_OK);
+        });
     };
 }
 
@@ -181,14 +237,23 @@ RUNNER_CHILD_TEST(security_manager_80_same_pkg_shared_ro_have_no_access_to_share
         AppInstallHelper nonSharedApp("sm_test_80_nonshared", sharedPkgName, OWNER_UID, version);
         ScopedInstaller nonSharedAppInstall(nonSharedApp);
 
-        runAccessTest(sharedApp2, sharedApp1.getPrivateDir(1), R_OK|W_OK|X_OK);
-        runAccessTest(sharedApp1, sharedApp2.getPrivateDir(2), R_OK|W_OK|X_OK);
-        runAccessTest(nonSharedApp, sharedApp1.getPrivateDir(1), R_OK|W_OK|X_OK);
-        runAccessTest(nonSharedApp, sharedApp2.getPrivateDir(2), R_OK|W_OK|X_OK);
+        runAccessTest(OWNER_UID, OWNER_GID, sharedApp1.getAppId(), [&]() {
+            accessTest(sharedApp1.getAppId(), sharedApp2.getPrivateDir(2), R_OK|W_OK|X_OK);
+        });
+        runAccessTest(OWNER_UID, OWNER_GID, sharedApp2.getAppId(), [&]() {
+            accessTest(sharedApp2.getAppId(), sharedApp1.getPrivateDir(1), R_OK|W_OK|X_OK);
+        });
+
+        runAccessTest(OWNER_UID, OWNER_GID, nonSharedApp.getAppId(), [&]() {
+            accessTest(nonSharedApp.getAppId(), sharedApp1.getPrivateDir(1), R_OK|W_OK|X_OK);
+            accessTest(nonSharedApp.getAppId(), sharedApp2.getPrivateDir(2), R_OK|W_OK|X_OK);
+        });
 
         sharedAppInstall1.uninstallApp();
 
-        runAccessTest(nonSharedApp, sharedApp2.getPrivateDir(2), R_OK|W_OK|X_OK);
+        runAccessTest(OWNER_UID, OWNER_GID, nonSharedApp.getAppId(), [&]() {
+            accessTest(nonSharedApp.getAppId(), sharedApp2.getPrivateDir(2), R_OK|W_OK|X_OK);
+        });
     }
 }
 
@@ -218,16 +283,22 @@ RUNNER_CHILD_TEST(security_manager_81_add_path_to_app_and_check_all)
         sharedRORequest.setUid(sharedApp2.getUID());
         Api::registerPaths(sharedRORequest);
 
-        runAccessTest(sharedApp, sharedApp.getSharedRODir(), R_OK|W_OK|X_OK);
-        runAccessTest(sharedApp, sharedApp.getPrivateDir(), R_OK|W_OK|X_OK);
-
-        runAccessTest(sharedApp2, sharedApp2.getSharedRODir(), R_OK|W_OK|X_OK);
-        runAccessTest(sharedApp2, sharedApp.getSharedRODir(), R_OK|X_OK);
-        runAccessTest(sharedApp2, sharedApp.getPrivateDir(), 0);
-
-        runAccessTest(nonSharedApp, sharedApp.getSharedRODir(), R_OK|X_OK);
-        runAccessTest(nonSharedApp, sharedApp2.getSharedRODir(), R_OK|X_OK);
-        runAccessTest(nonSharedApp, sharedApp.getPrivateDir(), 0);
+        runAccessTest(OWNER_UID, OWNER_GID, sharedApp.getAppId(), [&]() {
+            accessTest(sharedApp.getAppId(), sharedApp.getSharedRODir(), R_OK|W_OK|X_OK);
+            accessTest(sharedApp.getAppId(), sharedApp.getPrivateDir(), R_OK|W_OK|X_OK);
+        });
+
+        runAccessTest(OWNER_UID, OWNER_GID, sharedApp2.getAppId(), [&]() {
+            accessTest(sharedApp2.getAppId(), sharedApp2.getSharedRODir(), R_OK|W_OK|X_OK);
+            accessTest(sharedApp2.getAppId(), sharedApp.getSharedRODir(), R_OK|X_OK);
+            accessTest(sharedApp2.getAppId(), sharedApp.getPrivateDir(), 0);
+        });
+
+        runAccessTest(OWNER_UID, OWNER_GID, nonSharedApp.getAppId(), [&]() {
+            accessTest(nonSharedApp.getAppId(), sharedApp.getSharedRODir(), R_OK|X_OK);
+            accessTest(nonSharedApp.getAppId(), sharedApp2.getSharedRODir(), R_OK|X_OK);
+            accessTest(nonSharedApp.getAppId(), sharedApp.getPrivateDir(), 0);
+        });
     }
 }
 
@@ -270,12 +341,17 @@ RUNNER_CHILD_TEST(security_manager_83_install_uninstall_shared_ro_app_and_check_
         ScopedInstaller nonSharedAppInstall(nonSharedApp);
 
         sharedAppInstall1.uninstallApp();
+        sharedApp1.removePaths();
 
-        runAccessTest(nonSharedApp, sharedApp1.getSharedRODir(), 0);
-        runAccessTest(sharedApp2, sharedApp1.getSharedRODir(), 0);
+        runAccessTest(OWNER_UID, OWNER_GID, nonSharedApp.getAppId(), [&]() {
+            accessTest(nonSharedApp.getAppId(), sharedApp1.getSharedRODir(), 0);
+            accessTest(nonSharedApp.getAppId(), sharedApp2.getSharedRODir(), R_OK|X_OK);
+        });
 
-        runAccessTest(nonSharedApp, sharedApp2.getSharedRODir(), R_OK|X_OK);
-        runAccessTest(sharedApp2, sharedApp2.getSharedRODir(), R_OK|W_OK|X_OK);
+        runAccessTest(OWNER_UID, OWNER_GID, sharedApp2.getAppId(), [&]() {
+            accessTest(sharedApp2.getAppId(), sharedApp1.getSharedRODir(), 0);
+            accessTest(sharedApp2.getAppId(), sharedApp2.getSharedRODir(), R_OK|W_OK|X_OK);
+        });
     }
 }
 
@@ -302,7 +378,12 @@ RUNNER_CHILD_TEST(security_manager_84_install_uninstall_shared_ro_two_apps_in_on
 
         sharedAppInstall1.uninstallApp();
 
-        runAccessTest(nonSharedApp, sharedApp2.getSharedRODir(2), R_OK|X_OK);
-        runAccessTest(sharedApp2, sharedApp2.getSharedRODir(2), R_OK|W_OK|X_OK);
+        runAccessTest(OWNER_UID, OWNER_GID, nonSharedApp.getAppId(), [&]() {
+            accessTest(nonSharedApp.getAppId(), sharedApp2.getSharedRODir(2), R_OK|X_OK);
+        });
+
+        runAccessTest(OWNER_UID, OWNER_GID, sharedApp2.getAppId(), [&]() {
+            accessTest(sharedApp2.getAppId(), sharedApp2.getSharedRODir(2), R_OK|W_OK|X_OK);
+        });
     }
 }
index ba37c8b..26970c0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2016-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.
@@ -347,7 +347,7 @@ RUNNER_TEST(security_manager_66_path_req_check_labels)
     check_path(app.getPrivateDir(), generatePathRWLabel(app.getPkgId()));
     check_path(app.getPrivateRODir(), generatePathROLabel(app.getPkgId()), false);
     check_path(app.getPublicDir(), getPublicPathLabel());
-    check_path(app.getSharedRODir(), generatePathSharedROLabel(app.getPkgId()));
+    check_path(app.getSharedRODir(), getSharedROPathLabel());
 }
 
 RUNNER_TEST(security_manager_67_path_req_shared_ro_3_0)
@@ -367,7 +367,7 @@ RUNNER_TEST(security_manager_67_path_req_shared_ro_3_0)
     preq.addPath(app.getSharedRODir(), SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO);
 
     Api::registerPaths(preq);
-    check_path(app.getSharedRODir(), generatePathSharedROLabel(app.getPkgId()));
+    check_path(app.getSharedRODir(), getSharedROPathLabel());
 }
 
 RUNNER_TEST(security_manager_68_path_req_shared_ro_2_X)
@@ -387,7 +387,7 @@ RUNNER_TEST(security_manager_68_path_req_shared_ro_2_X)
     preq.addPath(app.getSharedRODir(), SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO);
 
     Api::registerPaths(preq);
-    check_path(app.getSharedRODir(), generatePathSharedROLabel(app.getPkgId()));
+    check_path(app.getSharedRODir(), getSharedROPathLabel());
 }
 
 RUNNER_TEST(security_manager_69_path_req_trusted_rw_no_author)