[SM] Apply/drop sharing tests 38/58538/4
authorZofia Abramowska <z.abramowska@samsung.com>
Fri, 29 Jan 2016 15:49:13 +0000 (16:49 +0100)
committerZofia Abramowska <z.abramowska@samsung.com>
Mon, 1 Feb 2016 20:59:58 +0000 (21:59 +0100)
Change-Id: I21e89b450726efef8041d128c4a2221e8dc7009e

src/security-manager-tests/CMakeLists.txt
src/security-manager-tests/common/app_install_helper.h
src/security-manager-tests/common/sm_api.cpp
src/security-manager-tests/common/sm_api.h
src/security-manager-tests/common/sm_db.cpp
src/security-manager-tests/common/sm_db.h
src/security-manager-tests/common/sm_sharing_request.cpp [new file with mode: 0644]
src/security-manager-tests/common/sm_sharing_request.h [new file with mode: 0644]
src/security-manager-tests/security_manager_tests.cpp

index 0f50b8e..c408eea 100644 (file)
@@ -44,6 +44,7 @@ SET(SEC_MGR_SOURCES
     ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_api.cpp
     ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_db.cpp
     ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_request.cpp
+    ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_sharing_request.cpp
     ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_user_request.cpp
     ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_policy_request.cpp
     ${PROJECT_SOURCE_DIR}/src/cynara-tests/common/cynara_test_client.cpp
index c79d263..a89db84 100644 (file)
@@ -36,6 +36,13 @@ struct AppInstallHelper {
         return getInstallDir() + "/trustedDir" + std::to_string(i);
     }
 
+    std::string getPrivateDir() {
+        return getInstallDir() + "/app_dir/";
+    }
+
+    std::string getSharedPath(int i = 0) {
+        return getPrivateDir() + "shareme" + std::to_string(i);
+    }
     std::string getAppId() {
         return m_name + "_app_id";
     }
@@ -45,11 +52,26 @@ struct AppInstallHelper {
     }
 
     void createInstallDir() {
-        mkdir(getInstallDir().c_str(), 0777);
+        if (mkdir(getInstallDir().c_str(), 0777) == 0) {
+            m_dirs.push_back(getInstallDir());
+        }
     }
 
     void createTrustedDir(int i = 0) {
-        mkdir(getTrustedDir(i).c_str(), 0777);
+        if (mkdir(getTrustedDir(i).c_str(), 0777) == 0) {
+            m_dirs.push_back(getTrustedDir(i));
+        }
+    }
+    void createPrivateDir() {
+        if (mkdir(getPrivateDir().c_str(), 0777) == 0) {
+            m_dirs.push_back(getPrivateDir());
+        }
+    }
+
+    void createSharedFile(int i = 0) {
+        if (creat(getSharedPath(i).c_str(), 0777) == 0) {
+            m_files.push_back(getSharedPath(i));
+        }
     }
 
     void revokeRules() {
@@ -71,11 +93,17 @@ struct AppInstallHelper {
 
     virtual ~AppInstallHelper() {
         // TODO we should also remove trusted dirs created with custom params
-        rmdir(getTrustedDir().c_str());
-        rmdir(getInstallDir().c_str());
+        for (const auto &dir : m_dirs) {
+            rmdir(dir.c_str());
+        }
+        for (const auto &file : m_files) {
+            unlink(file.c_str());
+        }
     }
 
 protected:
     std::string m_name;
+    std::vector<std::string> m_dirs;
+    std::vector<std::string> m_files;
 };
 
index 2e79f1b..604b171 100644 (file)
@@ -176,6 +176,20 @@ void getPolicy(const PolicyEntry &filter, std::vector<PolicyEntry> &policyEntrie
     };
 }
 
+void applySharing(const SharingRequest &req, lib_retcode expectedResult) {
+    int result = security_manager_private_sharing_apply(req.get());
+    RUNNER_ASSERT_MSG((lib_retcode)result == expectedResult,
+                      "Unexpected result from security_manager_private_sharing_apply" << std::endl
+                          << " Result: " << result << ";");
+}
+
+void dropSharing(const SharingRequest &req, lib_retcode expectedResult) {
+    int result = security_manager_private_sharing_drop(req.get());
+    RUNNER_ASSERT_MSG((lib_retcode)result == expectedResult,
+                      "Unexpected result from security_manager_private_sharing_drop" << std::endl
+                          << " Result: " << result << ";");
+}
+
 void getPolicyForSelf(const PolicyEntry &filter, std::vector<PolicyEntry> &policyEntries, lib_retcode expectedResult)
 {
     getConfiguredPolicy(filter, policyEntries, expectedResult, false);
index e96e249..2a3711b 100644 (file)
@@ -20,6 +20,7 @@
 #include <sm_request.h>
 #include <sm_user_request.h>
 #include <sm_policy_request.h>
+#include <sm_sharing_request.h>
 
 #include <security-manager.h>
 
@@ -45,6 +46,8 @@ void getPrivilegesMappings(const char *version_from,
                            const std::vector<std::string> &privileges,
                            std::vector<std::string> &mappings,
                            lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
+void applySharing(const SharingRequest &req, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
+void dropSharing(const SharingRequest &req, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
 } // namespace Api
 
 } // namespace SecurityManagerTest
index 7eb6f3f..d09703d 100644 (file)
@@ -263,3 +263,18 @@ int64_t TestSecurityManagerDatabase::get_author_id(const std::string &authorName
     return id;
 }
 
+std::string TestSecurityManagerDatabase::get_path_label(const std::string &path)
+{
+    Sqlite3DBaseSelectResult result;
+    std::ostringstream sql;
+    if (!m_base.is_open())
+        m_base.open();
+    sql.clear();
+    sql.str("SELECT path_label FROM shared_path WHERE path=\"" + path + "\"");
+    m_base.execute(sql.str(), result);
+
+    if(result.rows.empty())
+        return "";
+
+    return result.rows[0][0];
+}
index da71fbe..454996e 100644 (file)
@@ -170,6 +170,10 @@ public:
  * @brief Method for getting author id from database.
  */
     int64_t get_author_id(const std::string &authorName);
+/**
+ * @brief Method for path label from database.
+ */
+    std::string get_path_label(const std::string &path);
 private:
 /**
  * @var base
diff --git a/src/security-manager-tests/common/sm_sharing_request.cpp b/src/security-manager-tests/common/sm_sharing_request.cpp
new file mode 100644 (file)
index 0000000..3e361ec
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2014-2016 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.
+ */
+
+#include <sm_sharing_request.h>
+
+#include <dpl/test/test_runner.h>
+
+namespace SecurityManagerTest {
+
+SharingRequest::SharingRequest()
+    : m_req(nullptr)
+{
+    int result = security_manager_private_sharing_req_new(&m_req);
+    RUNNER_ASSERT_MSG((lib_retcode)result == SECURITY_MANAGER_SUCCESS,
+                      "creation of new request failed. Result: " << result);
+    RUNNER_ASSERT_MSG(m_req != nullptr, "creation of new request did not allocate memory");
+}
+
+SharingRequest::~SharingRequest()
+{
+    security_manager_private_sharing_req_free(m_req);
+}
+
+void SharingRequest::setOwnerAppId(const std::string &appId, lib_retcode expectedResult)
+{
+    int result = security_manager_private_sharing_req_set_owner_appid(m_req, appId.c_str());
+    RUNNER_ASSERT_MSG((lib_retcode)result == expectedResult,
+                      "setting app id returned wrong value."
+                          << " App id: " << appId << ";"
+                          << " Result: " << result << ";"
+                          << " Expected result: " << expectedResult);
+    m_appId = appId;
+}
+
+void SharingRequest::setTargetAppId(const std::string &appId, lib_retcode expectedResult)
+{
+    int result = security_manager_private_sharing_req_set_target_appid(m_req, appId.c_str());
+    RUNNER_ASSERT_MSG((lib_retcode)result == expectedResult,
+                      "setting app id returned wrong value."
+                          << " App id: " << appId << ";"
+                          << " Result: " << result << ";"
+                          << " Expected result: " << expectedResult);
+    m_appId = appId;
+}
+
+void SharingRequest::addPaths(const char **paths, size_t pathCount, lib_retcode expectedResult)
+{
+    int result = security_manager_private_sharing_req_add_paths(m_req, paths, pathCount);
+    RUNNER_ASSERT_MSG((lib_retcode)result == expectedResult,
+                      "adding path returned wrong value."
+                          << " Result: " << result << ";"
+                          << " Expected result: " << expectedResult);
+    for (size_t i = 0; i < pathCount; i++) {
+        m_paths.push_back(paths[i]);
+    }
+}
+
+std::ostream& operator<<(std::ostream &os, const SharingRequest &request)
+{
+
+    os << "app id: " << request.m_appId << "; ";
+    os << "pkg id: " << request.m_pkgId << "; ";
+
+    if (!request.m_paths.empty()) {
+        os << "paths: [ " << "< " << request.m_paths[0] << ">";
+        for (size_t i=1; i < request.m_paths.size(); ++i) {
+            os << "; < " << request.m_paths[i] << ">";
+        }
+        os << " ]";
+    }
+    return os;
+}
+
+} // namespace SecurityManagerTest
diff --git a/src/security-manager-tests/common/sm_sharing_request.h b/src/security-manager-tests/common/sm_sharing_request.h
new file mode 100644 (file)
index 0000000..e7f4107
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014-2016 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.
+ */
+
+#ifndef SECURITY_MANAGER_TEST_SHARINGREQUEST
+#define SECURITY_MANAGER_TEST_SHARINGREQUEST
+
+#include <iostream>
+#include <string>
+#include <sys/types.h>
+#include <utility>
+#include <vector>
+
+#include <security-manager.h>
+
+namespace SecurityManagerTest {
+
+class SharingRequest
+{
+public:
+    SharingRequest();
+    SharingRequest(const SharingRequest&) = delete;
+    SharingRequest& operator=(const SharingRequest&) = delete;
+    ~SharingRequest();
+
+    void setOwnerAppId(const std::string &appId, lib_retcode expectedresult = SECURITY_MANAGER_SUCCESS);
+    void setTargetAppId(const std::string &pkgId, lib_retcode expectedresult = SECURITY_MANAGER_SUCCESS);
+    void addPaths(const char **paths, size_t path_count,
+                 lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
+    const private_sharing_req *get() const { return m_req; }
+    friend std::ostream& operator<<(std::ostream &, const SharingRequest&);
+
+private:
+    private_sharing_req *m_req;
+
+    std::string m_appId;
+    std::string m_pkgId;
+    std::vector<std::string> m_paths;
+};
+
+std::ostream& operator<<(std::ostream &os, const SecurityManagerTest::SharingRequest &request);
+
+} // namespace SecurityManagerTest
+
+#endif // SECURITY_MANAGER_TEST_SHARINGREQUEST
index 417561c..e01fe67 100644 (file)
@@ -32,6 +32,7 @@
 #include <sm_api.h>
 #include <sm_db.h>
 #include <sm_request.h>
+#include <sm_sharing_request.h>
 #include <sm_user_request.h>
 #include <app_install_helper.h>
 #include <temp_test_user.h>
@@ -39,6 +40,7 @@
 #include <cynara_test_admin.h>
 #include <service_manager.h>
 #include <cynara_test_admin.h>
+#include "memory.h"
 
 using namespace SecurityManagerTest;
 
@@ -499,6 +501,41 @@ void check_exact_access(const std::string& subject, const std::string& object, c
     }
 }
 
+std::string access_opposite(std::string &access) {
+    static const std::map<char, int> access_mapping = {{'r', 0}, {'w', 1}, {'x', 2}, {'a', 3},
+                                                       {'t', 4}, {'l', 5}};
+    //May write implies may lock
+    if (access.find('w') != std::string::npos && access.find('l') == std::string::npos) {
+        access.append("l");
+    }
+    std::string access_opposite = "rwxatl";
+    for (char c : access) {
+        access_opposite[access_mapping.at(c)] = '-';
+    }
+    auto it = std::remove_if(access_opposite.begin(), access_opposite.end(), [](char c) {return c == '-';});
+    access_opposite.erase(it, access_opposite.end());
+    return access_opposite;
+}
+
+void check_exact_smack_accesses(const std::string &subject, const std::string &object, const std::string &access) {
+    std::string access_str(access);
+    auto no_access = access_opposite(access_str);
+    for (char c : access_str) {
+        int ret = smack_have_access(subject.c_str(), object.c_str(), std::string(1, c).c_str());
+        RUNNER_ASSERT_MSG(ret >= 0, "smack_have_access failed: <" << subject << ">, <" << object << ">, <" << c << "> errno=" << strerror(errno));
+        RUNNER_ASSERT_MSG(ret == 1, "Access " << c << " from " << subject << " to "
+                          << object << " not given");
+    }
+
+    for (char c : no_access) {
+        int ret = smack_have_access(subject.c_str(), object.c_str(), std::string(1, c).c_str());
+        RUNNER_ASSERT_MSG(ret >= 0, "smack_have_access failed: <" << subject << ">, <" << object << ">, <" << c << "> errno=" << strerror(errno));
+        RUNNER_ASSERT_MSG(ret == 0, "Access " << c << " from " << subject << " to "
+                          << object << " unnecessarily given");
+    }
+}
+
+
 RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER)
 
 
@@ -2759,6 +2796,540 @@ RUNNER_TEST(security_manager_27p_API30_app_uninstall)
     };
 }
 
+namespace {
+const char *const owner_access = "rwxat";
+const char *const target_path_access = "rxl";
+const char *const target_dir_access = "x";
+const char *const no_access = "";
+
+void check_system_access(const std::string pathLabel, bool apply = true) {
+    check_exact_smack_accesses("User", pathLabel, (apply ? owner_access : no_access));
+    check_exact_smack_accesses("System", pathLabel, (apply ? owner_access : no_access));
+}
+
+void check_owner_access(const std::string &ownerLabel, const std::string &pathLabel, bool apply = true) {
+    check_exact_smack_accesses(ownerLabel, pathLabel, (apply ? owner_access : no_access));
+}
+
+void check_target_access(const std::string &ownerPkgLabel, const std::string &targetLabel,
+        const std::string &pathLabel, bool pathShared = true, bool anyPathShared = true) {
+    check_exact_smack_accesses(targetLabel, pathLabel, (pathShared ? target_path_access : no_access));
+    check_exact_smack_accesses(targetLabel, ownerPkgLabel, (anyPathShared ? target_dir_access : no_access));
+}
+
+void check_path_label(const std::string &path, const std::string &expectedLabel) {
+    char *label = nullptr;
+    int ret = smack_new_label_from_path(path.c_str(), XATTR_NAME_SMACK, 0, &label);
+    RUNNER_ASSERT_MSG(ret > 0, "smack_new_label_from_path failed for " << path);
+    SmackLabelPtr realLabel(label);
+    RUNNER_ASSERT_MSG(realLabel.get() == expectedLabel, "Fetched label from " << path << " different"
+            " than expected, is : " << realLabel.get() << " should be " << expectedLabel);
+}
+
+void createFile(const std::string &filePath)
+{
+    //create temporary file and set label for it
+    mode_t systemMask;
+
+    unlink(filePath.c_str());
+    //allow to create file with 777 rights
+    systemMask = umask(0000);
+    int fd = open(filePath.c_str(), O_RDWR | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
+    //restore system mask
+    umask(systemMask);
+    RUNNER_ASSERT_ERRNO_MSG(fd > -1, "Unable to create file for tests");
+
+    //for descriptor protection
+    FdUniquePtr fd_ptr(&fd);
+
+    //change owner and group to user APP
+    int ret = chown(filePath.c_str(), APP_UID, APP_GID);
+    RUNNER_ASSERT_ERRNO_MSG(ret == 0, "Unable to change file owner");
+}
+
+}
+
+RUNNER_TEST(security_manager_30a_send_incomplete_req1)
+{
+    SharingRequest request;
+    Api::applySharing(request, SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE);
+    request.setOwnerAppId("someOwner");
+    Api::applySharing(request, SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE);
+    request.setTargetAppId("someTarget");
+    Api::applySharing(request, SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE);
+}
+
+RUNNER_TEST(security_manager_30b_send_incomplete_req2)
+{
+    SharingRequest request;
+    request.setTargetAppId("someTarget");
+    Api::applySharing(request, SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE);
+    request.setOwnerAppId("someOwner");
+    Api::applySharing(request, SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE);
+}
+
+RUNNER_TEST(security_manager_30c_send_incomplete_req3)
+{
+    SharingRequest request;
+    const char *somePaths[] = {"path1", "path2"};
+    request.addPaths(somePaths, sizeof(somePaths)/sizeof(somePaths[0]));
+    Api::applySharing(request, SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE);
+    request.setOwnerAppId("someOwner");
+    Api::applySharing(request, SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE);
+}
+
+RUNNER_TEST(security_manager_30d_unknown_owner)
+{
+    // This test depends on order of checks in security-manager service implementation
+    SharingRequest request;
+    request.setOwnerAppId("ImPrettySureIDontExist");
+    request.setTargetAppId("IDontMatter");
+    const char *somePaths[] = {"path1", "path2"};
+    request.addPaths(somePaths, sizeof(somePaths)/sizeof(somePaths[0]));
+    Api::applySharing(request, SECURITY_MANAGER_ERROR_APP_UNKNOWN);
+}
+
+RUNNER_TEST(security_manager_30e_unknown_target)
+{
+    // This test depends on order of checks in security-manager service implementation
+    AppInstallHelper owner("installedApp");
+    owner.revokeRules();
+    owner.createInstallDir();
+    InstallRequest ownerInst;
+    ownerInst.setAppId(owner.getAppId().c_str());
+    ownerInst.setPkgId(owner.getPkgId().c_str());
+    Api::install(ownerInst);
+
+    SharingRequest request;
+    request.setOwnerAppId(owner.getAppId());
+    request.setTargetAppId("NowImPrettySureIDontExist");
+    const char *somePaths[] = {"path1", "path2"};
+    request.addPaths(somePaths, sizeof(somePaths)/sizeof(somePaths[0]));
+    Api::applySharing(request, SECURITY_MANAGER_ERROR_APP_UNKNOWN);
+
+    Api::uninstall(ownerInst);
+}
+
+RUNNER_TEST(security_manager_30f_bad_paths)
+{
+    // This test depends on order of checks in security-manager service implementation
+    AppInstallHelper owner("installedApp");
+    owner.revokeRules();
+    owner.createInstallDir();
+    InstallRequest ownerInst;
+    ownerInst.setAppId(owner.getAppId().c_str());
+    ownerInst.setPkgId(owner.getPkgId().c_str());
+    Api::install(ownerInst);
+
+    AppInstallHelper target("secondInstalledApp");
+    target.revokeRules();
+    target.createInstallDir();
+    InstallRequest targetInst;
+    targetInst.setAppId(target.getAppId().c_str());
+    targetInst.setPkgId(target.getPkgId().c_str());
+    Api::install(targetInst);
+
+    SharingRequest request;
+    request.setOwnerAppId(owner.getAppId());
+    request.setTargetAppId(target.getAppId());
+
+    const char *somePath = "/tmp/somePath";
+    createFile(somePath);
+    const char *somePaths[] = {somePath};
+    request.addPaths(somePaths, sizeof(somePaths)/sizeof(somePaths[0]));
+    Api::applySharing(request, SECURITY_MANAGER_ERROR_APP_NOT_PATH_OWNER);
+
+    Api::uninstall(ownerInst);
+}
+
+RUNNER_TEST(security_manager_31_simple_share)
+{
+    std::vector<AppInstallHelper> helper {{"app30a"}, {"app30b"}};
+    auto &owner = helper[0];
+    auto &target = helper[1];
+
+    for (auto &e : helper) {
+        e.revokeRules();
+        e.createInstallDir();
+    }
+
+    owner.createPrivateDir();
+    owner.createSharedFile();
+
+    InstallRequest ownerReq;
+    ownerReq.setAppId(owner.getAppId().c_str());
+    ownerReq.setPkgId(owner.getPkgId().c_str());
+    ownerReq.addPath(owner.getSharedPath().c_str(), SECURITY_MANAGER_PATH_RW);
+    int result = nftw(owner.getInstallDir().c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS);
+    RUNNER_ASSERT_MSG(result == 0, "Unable to remove Smack labels in " << owner.getInstallDir());
+    Api::install(ownerReq);
+
+    InstallRequest targetReq;
+    targetReq.setAppId(target.getAppId().c_str());
+    targetReq.setPkgId(target.getAppId().c_str());
+    Api::install(targetReq);
+
+    SharingRequest share1;
+    std::string sharedPath = owner.getSharedPath().c_str();
+    share1.setOwnerAppId(owner.getAppId());
+    share1.setTargetAppId(target.getAppId());
+    const char *path[] = {sharedPath.c_str()};
+    share1.addPaths(path, 1);
+    Api::applySharing(share1);
+
+    TestSecurityManagerDatabase db;
+    std::string pathLabel1 = db.get_path_label(sharedPath.c_str());
+    RUNNER_ASSERT_MSG(!pathLabel1.empty(), "Couldn't fetch path label from database for file " << sharedPath);
+
+    check_system_access(pathLabel1);
+    check_owner_access(owner.generateAppLabel(), pathLabel1);
+    check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel1);
+    check_path_label(sharedPath, pathLabel1);
+
+    Api::dropSharing(share1);
+    check_system_access(pathLabel1, false);
+    check_owner_access(owner.generateAppLabel(), pathLabel1, false);
+    check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel1, false, false);
+    check_path_label(sharedPath, owner.generatePkgLabel());
+
+    Api::uninstall(ownerReq);
+    Api::uninstall(targetReq);
+}
+
+RUNNER_TEST(security_manager_32_double_share)
+{
+    std::vector<AppInstallHelper> helper {{"app31a"}, {"app31b"}};
+    auto &owner = helper[0];
+    auto &target = helper[1];
+
+    // cleanup
+    for (auto &e : helper) {
+        e.revokeRules();
+        e.createInstallDir();
+    }
+    owner.createPrivateDir();
+    owner.createSharedFile();
+
+    InstallRequest ownerReq;
+    ownerReq.setAppId(owner.getAppId().c_str());
+    ownerReq.setPkgId(owner.getPkgId().c_str());
+    ownerReq.addPath(owner.getSharedPath().c_str(), SECURITY_MANAGER_PATH_RW);
+
+    int result = nftw(owner.getInstallDir().c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS);
+    RUNNER_ASSERT_MSG(result == 0, "Unable to remove Smack labels in " << owner.getInstallDir());
+    Api::install(ownerReq);
+
+    InstallRequest targetReq;
+    targetReq.setAppId(target.getAppId().c_str());
+    targetReq.setPkgId(target.getAppId().c_str());
+    Api::install(targetReq);
+
+    SharingRequest share1;
+    std::string sharedPath = owner.getSharedPath(0).c_str();
+    share1.setOwnerAppId(owner.getAppId());
+    share1.setTargetAppId(target.getAppId());
+    const char *path[] = {sharedPath.c_str()};
+    share1.addPaths(path, 1);
+    Api::applySharing(share1);
+
+    TestSecurityManagerDatabase db;
+    std::string pathLabel = db.get_path_label(sharedPath.c_str());
+    RUNNER_ASSERT_MSG(!pathLabel.empty(), "Couldn't fetch path label from database for file " << sharedPath);
+
+    check_system_access(pathLabel);
+    check_owner_access(owner.generateAppLabel(), pathLabel);
+    check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel);
+    check_path_label(sharedPath, pathLabel);
+
+    Api::applySharing(share1);
+    check_system_access(pathLabel);
+    check_owner_access(owner.generateAppLabel(), pathLabel);
+    check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel);
+    check_path_label(sharedPath, pathLabel);
+
+    Api::dropSharing(share1);
+    check_system_access(pathLabel);
+    check_owner_access(owner.generateAppLabel(), pathLabel);
+    check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel);
+    check_path_label(sharedPath, pathLabel);
+
+    Api::dropSharing(share1);
+    check_system_access(pathLabel, false);
+    check_owner_access(owner.generateAppLabel(), pathLabel, false);
+    check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel, false, false);
+    check_path_label(sharedPath, owner.generatePkgLabel());
+
+    Api::uninstall(ownerReq);
+    Api::uninstall(targetReq);
+}
+RUNNER_TEST(security_manager_33_share_two_with_one)
+{
+    std::vector<AppInstallHelper> helper {{"app32a"}, {"app32b"}};
+    auto &owner = helper[0];
+    auto &target = helper[1];
+
+    // cleanup
+    for (auto &e : helper) {
+        e.revokeRules();
+        e.createInstallDir();
+    }
+    owner.createPrivateDir();
+    owner.createSharedFile(0);
+    owner.createSharedFile(1);
+
+    InstallRequest ownerReq;
+    ownerReq.setAppId(owner.getAppId().c_str());
+    ownerReq.setPkgId(owner.getPkgId().c_str());
+    ownerReq.addPath(owner.getSharedPath(0).c_str(), SECURITY_MANAGER_PATH_RW);
+    ownerReq.addPath(owner.getSharedPath(1).c_str(), SECURITY_MANAGER_PATH_RW);
+
+    int result = nftw(owner.getInstallDir().c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS);
+    RUNNER_ASSERT_MSG(result == 0, "Unable to remove Smack labels in " << owner.getInstallDir());
+    Api::install(ownerReq);
+
+    InstallRequest targetReq;
+    targetReq.setAppId(target.getAppId().c_str());
+    targetReq.setPkgId(target.getAppId().c_str());
+    Api::install(targetReq);
+
+    SharingRequest share1, share2;
+    std::string sharedPath1 = owner.getSharedPath(0).c_str();
+    std::string sharedPath2 = owner.getSharedPath(1).c_str();
+    share1.setOwnerAppId(owner.getAppId());
+    share2.setOwnerAppId(owner.getAppId());
+    share1.setTargetAppId(target.getAppId());
+    share2.setTargetAppId(target.getAppId());
+    const char *path1[] = {sharedPath1.c_str()};
+    const char *path2[] = {sharedPath2.c_str()};
+    share1.addPaths(path1, 1);
+    share2.addPaths(path2, 1);
+
+    Api::applySharing(share1);
+    TestSecurityManagerDatabase db;
+    std::string pathLabel1 = db.get_path_label(sharedPath1.c_str());
+    RUNNER_ASSERT_MSG(!pathLabel1.empty(), "Couldn't fetch path label from database for file " << sharedPath1);
+
+    check_system_access(pathLabel1);
+    check_owner_access(owner.generateAppLabel(), pathLabel1);
+    check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel1);
+    check_path_label(sharedPath1, pathLabel1);
+
+    Api::applySharing(share2);
+    std::string pathLabel2 = db.get_path_label(sharedPath2.c_str());
+    RUNNER_ASSERT_MSG(!pathLabel2.empty(), "Couldn't fetch path label from database for file " << sharedPath2);
+    RUNNER_ASSERT_MSG(pathLabel1 != pathLabel2, "Labels for private shared paths should be unique!");
+
+    check_system_access(pathLabel1);
+    check_system_access(pathLabel2);
+    check_owner_access(owner.generateAppLabel(), pathLabel1);
+    check_owner_access(owner.generateAppLabel(), pathLabel2);
+    check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel1);
+    check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel2);
+    check_path_label(sharedPath1, pathLabel1);
+    check_path_label(sharedPath2, pathLabel2);
+
+    Api::dropSharing(share1);
+    check_system_access(pathLabel1, false);
+    check_system_access(pathLabel2);
+    check_owner_access(owner.generateAppLabel(), pathLabel1, false);
+    check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel1, false);
+    check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel2);
+    check_path_label(sharedPath1, owner.generatePkgLabel());
+    check_path_label(sharedPath2, pathLabel2);
+
+    Api::dropSharing(share2);
+    check_system_access(pathLabel1, false);
+    check_system_access(pathLabel2, false);
+    check_owner_access(owner.generateAppLabel(), pathLabel1, false);
+    check_owner_access(owner.generateAppLabel(), pathLabel2, false);
+    check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel1, false, false);
+    check_target_access(owner.generatePkgLabel(), target.generateAppLabel(), pathLabel2, false, false);
+    check_path_label(sharedPath1, owner.generatePkgLabel());
+    check_path_label(sharedPath2, owner.generatePkgLabel());
+
+    Api::uninstall(ownerReq);
+    Api::uninstall(targetReq);
+}
+
+RUNNER_TEST(security_manager_34_share_one_with_two)
+{
+    std::vector<AppInstallHelper> helper {{"app33a"}, {"app33b"}, {"app33c"}};
+    auto &owner = helper[0];
+    auto &target1 = helper[1];
+    auto &target2 = helper[2];
+
+    // cleanup
+    for (auto &e : helper) {
+        e.revokeRules();
+        e.createInstallDir();
+    }
+    owner.createPrivateDir();
+    owner.createSharedFile();
+
+    InstallRequest ownerReq;
+    ownerReq.setAppId(owner.getAppId().c_str());
+    ownerReq.setPkgId(owner.getPkgId().c_str());
+    ownerReq.addPath(owner.getSharedPath().c_str(), SECURITY_MANAGER_PATH_RW);
+    int result = nftw(owner.getInstallDir().c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS);
+    RUNNER_ASSERT_MSG(result == 0, "Unable to remove Smack labels in " << owner.getInstallDir());
+    Api::install(ownerReq);
+
+    for (size_t i = 1; i < helper.size(); i++) {
+        InstallRequest targetReq;
+        targetReq.setAppId(helper[i].getAppId().c_str());
+        targetReq.setPkgId(helper[i].getAppId().c_str());
+        Api::install(targetReq);
+    }
+
+    SharingRequest share1, share2;
+    std::string sharedPath = owner.getSharedPath(0).c_str();
+    share1.setOwnerAppId(owner.getAppId());
+    share2.setOwnerAppId(owner.getAppId());
+    share1.setTargetAppId(target1.getAppId());
+    share2.setTargetAppId(target2.getAppId());
+
+    const char *path[] = {sharedPath.c_str()};
+    share1.addPaths(path, 1);
+    share2.addPaths(path, 1);
+
+    Api::applySharing(share1);
+    TestSecurityManagerDatabase db;
+    std::string pathLabel = db.get_path_label(sharedPath.c_str());
+    RUNNER_ASSERT_MSG(!pathLabel.empty(), "Couldn't fetch path label from database for file " << sharedPath);
+
+    check_system_access(pathLabel);
+    check_owner_access(owner.generateAppLabel(), pathLabel);
+    check_target_access(owner.generatePkgLabel(), target1.generateAppLabel(), pathLabel);
+    check_path_label(sharedPath, pathLabel);
+
+    Api::applySharing(share2);
+    check_system_access(pathLabel);
+    check_owner_access(owner.generateAppLabel(), pathLabel);
+    check_target_access(owner.generatePkgLabel(), target1.generateAppLabel(), pathLabel);
+    check_target_access(owner.generatePkgLabel(), target2.generateAppLabel(), pathLabel);
+    check_path_label(sharedPath, pathLabel);
+
+    Api::dropSharing(share1);
+    check_system_access(pathLabel);
+    check_owner_access(owner.generateAppLabel(), pathLabel);
+    check_target_access(owner.generatePkgLabel(), target1.generateAppLabel(), pathLabel, false, false);
+    check_target_access(owner.generatePkgLabel(), target2.generateAppLabel(), pathLabel);
+    check_path_label(sharedPath, pathLabel);
+
+    Api::dropSharing(share2);
+    check_system_access(pathLabel, false);
+    check_owner_access(owner.generateAppLabel(), pathLabel, false);
+    check_target_access(owner.generatePkgLabel(), target1.generateAppLabel(), pathLabel, false, false);
+    check_target_access(owner.generatePkgLabel(), target2.generateAppLabel(), pathLabel, false, false);
+    check_path_label(sharedPath, owner.generatePkgLabel());
+
+    Api::uninstall(ownerReq);
+    for (size_t i = 1; i < helper.size(); i++) {
+        InstallRequest targetReq;
+        targetReq.setAppId(helper[i].getAppId().c_str());
+        targetReq.setPkgId(helper[i].getAppId().c_str());
+        Api::uninstall(targetReq);
+    }
+}
+
+RUNNER_TEST(security_manager_35_share_two_with_two)
+{
+    std::vector<AppInstallHelper> helper {{"app34a"}, {"app34b"}, {"app34c"}};
+    auto &owner = helper[0];
+    auto &target1 = helper[1];
+    auto &target2 = helper[2];
+
+    // cleanup
+    for (auto &e : helper) {
+        e.revokeRules();
+        e.createInstallDir();
+    }
+    owner.createPrivateDir();
+    owner.createSharedFile(0);
+    owner.createSharedFile(1);
+
+    InstallRequest ownerReq;
+    ownerReq.setAppId(owner.getAppId().c_str());
+    ownerReq.setPkgId(owner.getPkgId().c_str());
+    ownerReq.addPath(owner.getSharedPath(0).c_str(), SECURITY_MANAGER_PATH_RW);
+    ownerReq.addPath(owner.getSharedPath(1).c_str(), SECURITY_MANAGER_PATH_RW);
+
+    int result = nftw(owner.getInstallDir().c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS);
+    RUNNER_ASSERT_MSG(result == 0, "Unable to remove Smack labels in " << owner.getInstallDir());
+    Api::install(ownerReq);
+
+    for (size_t i = 1; i < helper.size(); i++) {
+        InstallRequest targetReq;
+        targetReq.setAppId(helper[i].getAppId().c_str());
+        targetReq.setPkgId(helper[i].getAppId().c_str());
+        Api::install(targetReq);
+    }
+
+    SharingRequest share1, share2;
+    std::string sharedPath1 = owner.getSharedPath(0).c_str();
+    std::string sharedPath2 = owner.getSharedPath(1).c_str();
+    share1.setOwnerAppId(owner.getAppId());
+    share2.setOwnerAppId(owner.getAppId());
+    share1.setTargetAppId(target1.getAppId());
+    share2.setTargetAppId(target2.getAppId());
+
+    const char *path1[] = {sharedPath1.c_str()};
+    const char *path2[] = {sharedPath2.c_str()};
+    share1.addPaths(path1, 1);
+    share2.addPaths(path2, 1);
+
+    Api::applySharing(share1);
+    TestSecurityManagerDatabase db;
+    std::string pathLabel1 = db.get_path_label(sharedPath1.c_str());
+    RUNNER_ASSERT_MSG(!pathLabel1.empty(), "Couldn't fetch path label from database for file " << sharedPath1);
+
+    check_system_access(pathLabel1);
+    check_owner_access(owner.generateAppLabel(), pathLabel1);
+    check_target_access(owner.generatePkgLabel(), target1.generateAppLabel(), pathLabel1);
+    check_path_label(sharedPath1, pathLabel1);
+
+    Api::applySharing(share2);
+    std::string pathLabel2 = db.get_path_label(sharedPath2.c_str());
+    RUNNER_ASSERT_MSG(!pathLabel2.empty(), "Couldn't fetch path label from database for file " << sharedPath2);
+    RUNNER_ASSERT_MSG(pathLabel1 != pathLabel2, "Labels for shared files should be unique!");
+
+    check_system_access(pathLabel1);
+    check_system_access(pathLabel2);
+    check_owner_access(owner.generateAppLabel(), pathLabel1);
+    check_owner_access(owner.generateAppLabel(), pathLabel2);
+    check_target_access(owner.generatePkgLabel(), target1.generateAppLabel(), pathLabel1);
+    check_target_access(owner.generatePkgLabel(), target2.generateAppLabel(), pathLabel2);
+    check_path_label(sharedPath1, pathLabel1);
+    check_path_label(sharedPath2, pathLabel2);
+
+    Api::dropSharing(share2);
+    check_system_access(pathLabel1);
+    check_system_access(pathLabel2, false);
+    check_owner_access(owner.generateAppLabel(), pathLabel1);
+    check_owner_access(owner.generateAppLabel(), pathLabel2, false);
+    check_target_access(owner.generatePkgLabel(), target1.generateAppLabel(), pathLabel1);
+    check_target_access(owner.generatePkgLabel(), target2.generateAppLabel(), pathLabel2, false, false);
+    check_path_label(sharedPath1, pathLabel1);
+    check_path_label(sharedPath2, owner.generatePkgLabel());
+
+    Api::dropSharing(share1);
+    check_system_access(pathLabel1, false);
+    check_system_access(pathLabel2, false);
+    check_owner_access(owner.generateAppLabel(), pathLabel1, false);
+    check_owner_access(owner.generateAppLabel(), pathLabel2, false);
+    check_target_access(owner.generatePkgLabel(), target1.generateAppLabel(), pathLabel1, false, false);
+    check_target_access(owner.generatePkgLabel(), target2.generateAppLabel(), pathLabel2, false, false);
+    check_path_label(sharedPath1, owner.generatePkgLabel());
+    check_path_label(sharedPath2, owner.generatePkgLabel());
+    Api::uninstall(ownerReq);
+    for (size_t i = 1; i < helper.size(); i++) {
+        InstallRequest targetReq;
+        targetReq.setAppId(helper[i].getAppId().c_str());
+        targetReq.setPkgId(helper[i].getAppId().c_str());
+        Api::uninstall(targetReq);
+    }
+}
+
 RUNNER_TEST(security_manager_40_set_wrong_author_id)
 {
     InstallRequest requestInst;