Change shared/data handle logic 03/210403/22
authorJunghyun Yeon <jungh.yeon@samsung.com>
Fri, 19 Jul 2019 00:47:03 +0000 (09:47 +0900)
committerJunghyun Yeon <jungh.yeon@samsung.com>
Thu, 21 Nov 2019 07:55:28 +0000 (07:55 +0000)
- Create shared data directory for each package at
  certain directory to prevent creation of N^2 smack labels.
- Create symlink at previous location for backward compatibility.

Change-Id: Ibb52bfef6843e3d38f91eabb418d87b46a4e918b
Signed-off-by: Junghyun Yeon <jungh.yeon@samsung.com>
src/common/security_registration.cc
src/common/shared_dirs.cc
src/common/shared_dirs.h
src/common/step/filesystem/step_create_storage_directories.cc
src/common/step/filesystem/step_remove_files.cc
src/common/step/filesystem/step_update_storage_directories.cc
src/common/utils/file_util.cc
src/common/utils/file_util.h
src/unit_tests/common/smoke_utils.cc

index 8488f22..35d6b26 100644 (file)
@@ -343,7 +343,8 @@ class SecurityContextPathRequest {
       } else {
         if (!bf::exists(subpath))
           continue;
-        if (bf::is_symlink(symlink_status(subpath))) {
+        if (bf::is_symlink(symlink_status(subpath)) &&
+            policy.second != SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO) {
           LOG(DEBUG) << "Path " << subpath << " is a symlink."
                      << "Path will not be registered";
           continue;
index c551f57..2fed198 100644 (file)
@@ -65,10 +65,18 @@ const std::vector<std::string> kReadOnlyEntries = {
   {"res"},
   {"shared/res"},
 };
+const std::vector<std::string> kSharedDataEntries = {
+  {".shared"},
+  {".shared_tmp"},
+};
 
 const char kSharedResDir[] = "shared/res";
 const char kSharedCacheDir[] = "shared/cache";
 const char kSharedDataDir[] = "shared/data";
+const char kShared[] = "shared";
+const char kData[] = "data";
+const char kSharedDir[] = ".shared";
+const char kSharedTmpDir[] = ".shared_tmp";
 const char kSharedTrustedDir[] = "shared/trusted";
 const char kSkelAppDir[] = "skel/apps_rw";
 const char kExternalStoragePrivilege[] =
@@ -94,6 +102,20 @@ bool SetDirectoryOwnerAndPermissions(const bf::path& subpath, uid_t uid,
                                                          uid, gid);
 }
 
+bool SetSharedDirOwnerAndPermissions(const bf::path& subpath, uid_t uid) {
+  if (!bf::is_directory(subpath) || subpath.filename() != "data")
+    return true;
+  bf::perms perms = (bf::all_all | bf::set_uid_on_exe) ^ bf::others_write;
+  boost::optional<gid_t> system_share =
+    ci::GetGidByGroupName(kSystemShareGroupName);
+  if (!system_share)
+    return false;
+  gid_t gid = *system_share;
+
+  return common_installer::SetDirOwnershipAndPermissions(subpath, perms,
+      uid, gid);
+}
+
 bool CreateDirectories(const bf::path& app_dir, const std::string& pkgid,
                        uid_t uid, gid_t gid, const bool set_permissions,
                        const std::vector<const char*>
@@ -176,12 +198,50 @@ bool CreateUserDirectories(uid_t user, const std::string& pkgid,
   return true;
 }
 
+bool DeleteSharedDataDirectories(const bf::path& path,
+                                 const std::string& pkgid) {
+  if (!ci::Remove(path / pkgid / kSharedDataDir))
+    return false;
+
+  std::vector<std::string> shared_dirs(kSharedDataEntries);
+  for (auto entry : shared_dirs) {
+    if (!ci::RemoveAll(path / entry / pkgid))
+      return false;
+  }
+
+  return true;
+}
+
+bool CreateSharedDataDirectories(const bf::path& path,
+                                 const std::string& pkgid) {
+  if (!ci::CreateDir(path / kSharedDir / pkgid / kData) ||
+      !ci::CreateDir(path / kSharedTmpDir / pkgid))
+    return false;
+
+  bf::current_path(path / pkgid / kShared);
+  if (bf::exists(path / pkgid / kShared / kData))
+    return true;
+  bf::path relative_path = ci::RelativePath(path / kSharedDir / pkgid / kData,
+                                            bf::current_path() / kData);
+  bs::error_code error;
+  bf::create_symlink(relative_path, kData, error);
+  if (error) {
+    LOG(ERROR) << "Failed to create symlink : " << error.message();
+    return false;
+  }
+
+  return true;
+}
+
 bool DeleteDirectories(const bf::path& app_dir, const std::string& pkgid) {
   bf::path base_dir = app_dir / pkgid;
-  return ci::RemoveAll(base_dir);
+  if (!ci::RemoveAll(base_dir))
+    return false;
+  if (!DeleteSharedDataDirectories(app_dir, pkgid))
+    return false;
+  return true;
 }
 
-
 bool CreateSymlinkFiles(const bf::path& src_dir, const bf::path& dst_dir) {
   std::vector<std::string> rofiles(kReadOnlyEntries);
   for (bf::directory_iterator file(src_dir);
@@ -263,15 +323,19 @@ bool DeleteSymlinkFiles(const bf::path& src_dir, const bf::path& dst_dir) {
   return true;
 }
 
-bool CreateStorageDirectories(const boost::filesystem::path& path,
+bool CreateStorageDirectories(const boost::filesystem::path& root_path,
+                              const std::string& pkgid,
                               bool trusted, bool shareddata,
                               const std::vector<const char*> additional_dirs) {
+  bf::path path(root_path / pkgid);
   if (!bf::exists(path)) {
     LOG(DEBUG) << "Creating directories in: " << path;
     bs::error_code error;
     bf::create_directories(path, error);
     if (error) {
-      LOG(ERROR) << "Failed to create directory: " << path;
+      LOG(ERROR) << "Failed to create directory: "
+                 << path << ", error: "
+                 << error.message();
       return false;
     }
   }
@@ -280,16 +344,9 @@ bool CreateStorageDirectories(const boost::filesystem::path& path,
   dirs.insert(dirs.end(), additional_dirs.begin(), additional_dirs.end());
   if (trusted)
     dirs.push_back(kSharedTrustedDir);
-  if (shareddata) {
-    dirs.push_back(kSharedDataDir);
-  } else {
-    bf::path shared_data_path = path / kSharedDataDir;
-    // remove shared/data (deprecated)
-    if (!ci::RemoveAll(shared_data_path))
-      return false;
-  }
+
+  bs::error_code error;
   for (auto& entry : dirs) {
-    bs::error_code error;
     bf::path subpath = path / entry;
     bf::create_directories(subpath, error);
     if (error && !bf::exists(subpath)) {
@@ -298,6 +355,14 @@ bool CreateStorageDirectories(const boost::filesystem::path& path,
     }
   }
 
+  if (shareddata) {
+    if (!CreateSharedDataDirectories(root_path, pkgid))
+      return false;
+  } else {
+    if (!DeleteSharedDataDirectories(root_path, pkgid))
+      return false;
+  }
+
   bf::path shared_cache_path = path / kSharedCacheDir;
   // remove shared/cache (do not support)
   if (!ci::RemoveAll(shared_cache_path))
@@ -435,8 +500,8 @@ bool PerformExternalDirectoryDeletionForAllUsers(const std::string& pkgid) {
 bool CreateStorageDirectories(const boost::filesystem::path& path,
                               const std::string& pkgid, uid_t uid,
                               bool trusted, bool shareddata) {
-  if (!::CreateStorageDirectories(path, trusted, shareddata,
-                                  std::vector<const char*>())) {
+  if (!::CreateStorageDirectories(path, pkgid, trusted,
+                                  shareddata, std::vector<const char*>())) {
     LOG(ERROR) << "Failed to create storage directory for path: " << path;
     return false;
   }
@@ -452,37 +517,46 @@ bool CreateStorageDirectories(const boost::filesystem::path& path,
   return true;
 }
 
-bool DeleteStorageDirectories(const boost::filesystem::path& path) {
+bool DeleteStorageDirectories(const boost::filesystem::path& path,
+                              const std::string& pkgid) {
   std::vector<const char*> dirs;
   dirs.assign(kEntries.begin() + 1, kEntries.end());
   dirs.push_back(kSharedTrustedDir);
-  dirs.push_back(kSharedDataDir);
   dirs.push_back(kSharedCacheDir);
   for (auto& entry : dirs) {
-    bf::path subpath = path / entry;
+    bf::path subpath = path / pkgid / entry;
     if (!ci::RemoveAll(subpath))
       return false;
   }
+  if (!DeleteSharedDataDirectories(path, pkgid))
+    return false;
+
   return true;
 }
 
+bool DeleteSharedDirectories(const bf::path& path,
+                             const std::string& pkgid) {
+  return DeleteSharedDataDirectories(path, pkgid);
+}
+
 bool CreateSkelDirectories(const std::string& pkgid,
                            bool trusted, bool shareddata, bool is_readonly,
                            const std::vector<const char*> additional_dirs) {
-  bf::path path = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
-                  bf::path(kSkelAppDir) / pkgid;
-  LOG(DEBUG) << "Creating directories in: " << path;
+  bf::path root_path = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
+                       bf::path(kSkelAppDir);
 
-  if (!::CreateStorageDirectories(path, trusted, shareddata,
-                                  additional_dirs)) {
-    LOG(ERROR) << "Failed to create storage directory for path: " << path;
+  if (!::CreateStorageDirectories(root_path, pkgid, trusted,
+                                  shareddata, additional_dirs)) {
+    LOG(ERROR) << "Failed to create storage directory for path: "
+               << root_path / pkgid;
     return false;
   }
 
   std::string error_message;
-  if (!RegisterSecurityContextForPath(pkgid, path, kGlobalUserUid,
+  if (!RegisterSecurityContextForPath(pkgid, root_path / pkgid, kGlobalUserUid,
                                       is_readonly, &error_message)) {
-    LOG(ERROR) << "Failed to register security context for path: " << path
+    LOG(ERROR) << "Failed to register security context for path: "
+               << root_path / pkgid
                << ", error_message: " << error_message;
     return false;
   }
@@ -490,7 +564,7 @@ bool CreateSkelDirectories(const std::string& pkgid,
   bool result = true;
   if (!is_readonly) {
     bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
-    result = CreateSymlinkFiles(src_dir, path);
+    result = CreateSymlinkFiles(src_dir, root_path / pkgid);
   }
 
   return result;
@@ -498,33 +572,39 @@ bool CreateSkelDirectories(const std::string& pkgid,
 
 bool UpdateSkelDirectories(const std::string& pkgid,
                            bool is_remove_shareddata) {
-  bf::path path = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
-                  bf::path(kSkelAppDir) / pkgid;
-  bf::path shared_data_path = path / kSharedDataDir;
+  bf::path root_path = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
+                       bf::path(kSkelAppDir);
   LOG(DEBUG) << ((is_remove_shareddata) ? "Removing" : "Creating")
-             << " directory : " << shared_data_path;
-
-  if (!is_remove_shareddata) {
-    if (!CreateDir(shared_data_path))
+             << " skel directory for pkgid: " << pkgid;
+  if (is_remove_shareddata) {
+    if (!DeleteSharedDataDirectories(root_path, pkgid))
       return false;
+    return true;
+  }
 
-    std::string error_message;
-    if (!RegisterSecurityContextForPath(pkgid, path, kGlobalUserUid,
-                                        false, &error_message)) {
-      LOG(ERROR) << "Failed to register security context for path: " << path
-                 << ", error_message: " << error_message;
-      return false;
-    }
-  } else {
-    return ci::RemoveAll(shared_data_path);
+  if (!CreateSharedDataDirectories(root_path, pkgid))
+    return false;
+
+  std::string error_message;
+  if (!RegisterSecurityContextForPath(pkgid, root_path / pkgid, kGlobalUserUid,
+                                      false, &error_message)) {
+    LOG(ERROR) << "Failed to register security context for path: "
+               << root_path / pkgid
+               << ", error_message: " << error_message;
+    return false;
   }
+
   return true;
 }
 
 bool DeleteSkelDirectories(const std::string& pkgid) {
   bf::path path = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
                   bf::path(kSkelAppDir);
-  return DeleteDirectories(path, pkgid);
+  if (!DeleteDirectories(path, pkgid))
+    return false;
+
+  return DeleteSharedDataDirectories(
+      bf::path(tzplatform_getenv(TZ_SYS_ETC)) / bf::path(kSkelAppDir), pkgid);
 }
 
 
@@ -572,14 +652,36 @@ bool CopyUserDirectories(const std::string& pkgid) {
   UserList list = ci::GetUserList();
   for (auto l : list) {
     uid_t uid = std::get<0>(l);
+    gid_t gid = std::get<1>(l);
     LOG(DEBUG) << "Copying directories for uid: " << uid;
     bf::path apps_rw(std::get<2>(l) / "apps_rw");
     bf::path src = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
                    bf::path(kSkelAppDir) / pkgid;
     bf::path dst = apps_rw / pkgid;
-    if (!ci::CopyDir(src, dst, FSFlag::FS_NONE, true))
+    if (!ci::CopyDir(src, dst, FSFlag::FS_NONE, false))
       continue;
-    gid_t gid = std::get<1>(l);
+
+    std::vector<std::string> shared_dirs(kSharedDataEntries);
+    for (auto entry : shared_dirs) {
+      bf::path shared_src = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
+          bf::path(kSkelAppDir) / entry / pkgid;
+      if (!bf::exists(shared_src))
+        break;
+
+      bf::path shared_dst = apps_rw / entry / pkgid;
+      if (!ci::CopyDir(shared_src, shared_dst, FSFlag::FS_NONE, true))
+        continue;
+
+      if (!SetDirectoryOwnerAndPermissions(shared_dst, uid, gid))
+        return false;
+
+      for (bf::recursive_directory_iterator iter(dst);
+          iter != bf::recursive_directory_iterator(); ++iter) {
+        if (!SetSharedDirOwnerAndPermissions(iter->path(), uid))
+          return false;
+      }
+    }
+
     if (!SetDirectoryOwnerAndPermissions(dst, uid, gid))
       return false;
     for (bf::recursive_directory_iterator iter(dst);
@@ -599,43 +701,57 @@ bool CopyUserDirectories(const std::string& pkgid) {
   return true;
 }
 
+bool CreateSharedData(const bf::path& path,
+                      const std::string& pkgid) {
+  return CreateSharedDataDirectories(path, pkgid);
+}
+
 bool UpdateUserDirectory(const std::string& pkgid, bool is_remove_shareddata) {
   UserList list = ci::GetUserList();
   for (auto l : list) {
-    bf::path apps_rw(std::get<2>(l) / "apps_rw");
-    bf::path root_dst = apps_rw / pkgid;
-    bf::path shareddir_dst = root_dst / kSharedDataDir;
+    bf::path root_path(std::get<2>(l) / "apps_rw");
+    bf::path pkg_path(root_path / pkgid);
     uid_t uid = std::get<0>(l);
     LOG(DEBUG) << ((is_remove_shareddata) ? "Deleting" : "Adding")
                << " shareddata directory for uid: " << uid;
 
-    if (!is_remove_shareddata) {
-      bs::error_code error;
-      bf::create_directories(shareddir_dst, error);
-      if (error && !bf::exists(shareddir_dst)) {
-        LOG(ERROR) << "Failed to create directory: " << shareddir_dst;
-        return false;
-      }
+    if (is_remove_shareddata)
+      return DeleteSharedDataDirectories(root_path, pkgid);
+
+    if (!CreateSharedDataDirectories(root_path, pkgid)) {
+      LOG(ERROR) << "Failed to create shared directory: "
+                 << root_path / pkgid;
+      return false;
+    }
 
-      gid_t gid = std::get<1>(l);
-      if (!SetDirectoryOwnerAndPermissions(root_dst, uid, gid))
+    gid_t gid = std::get<1>(l);
+    std::vector<std::string> shared_dirs(kSharedDataEntries);
+    for (auto entry : shared_dirs) {
+      bf::path dst = root_path / entry / pkgid;
+      if (!SetDirectoryOwnerAndPermissions(dst, uid, gid))
         return false;
-      for (bf::recursive_directory_iterator iter(root_dst);
+      for (bf::recursive_directory_iterator iter(dst);
           iter != bf::recursive_directory_iterator(); ++iter) {
-        if (!SetDirectoryOwnerAndPermissions(iter->path(),
-            uid, gid))
+        if (!SetSharedDirOwnerAndPermissions(iter->path(), uid))
           return false;
       }
+    }
 
-      std::string error_message;
-      if (!RegisterSecurityContextForPath(pkgid, root_dst, uid,
-          false, &error_message)) {
-        LOG(ERROR) << "Failed to register security context for path: "
-                   << root_dst << ", error_message: " << error_message;
+    if (!SetDirectoryOwnerAndPermissions(pkg_path, uid, gid))
+      return false;
+    for (bf::recursive_directory_iterator iter(pkg_path);
+        iter != bf::recursive_directory_iterator(); ++iter) {
+      if (!SetDirectoryOwnerAndPermissions(iter->path(),
+          uid, gid))
         return false;
-      }
-    } else {
-      return ci::RemoveAll(shareddir_dst);
+    }
+
+    std::string error_message;
+    if (!RegisterSecurityContextForPath(pkgid, pkg_path, uid,
+        false, &error_message)) {
+      LOG(ERROR) << "Failed to register security context for path: "
+                  << pkg_path << ", error_message: " << error_message;
+      return false;
     }
   }
   return true;
index e1f0b3c..5d9a085 100644 (file)
@@ -82,10 +82,23 @@ bool CreateStorageDirectories(const boost::filesystem::path& path,
  * \brief Deletes storage directories in path
  *
  * \param path base path, which contains storage directories
+ * \param pkgid package id
+ *
+ * \return true if succeed, false otherwise
+ */
+bool DeleteStorageDirectories(const boost::filesystem::path& path,
+                              const std::string& pkgid);
+
+/**
+ * \brief Deletes shared directories in path
+ *
+ * \param path base path, which containsshared directories
+ * \param pkgid package id
  *
  * \return true if succeed, false otherwise
  */
-bool DeleteStorageDirectories(const boost::filesystem::path& path);
+bool DeleteSharedDirectories(const boost::filesystem::path& path,
+                             const std::string& pkgid);
 
 /**
  * \brief Create skeleton directories for package
@@ -159,6 +172,18 @@ bool UpdateUserDirectory(const std::string& pkgid,
                            bool is_remove_shareddata);
 
 /**
+ * \brief Create shared-data directories
+ *
+ * \param path root path
+ * \param pkgid package id
+  *
+ * \return true if succeed, false otherwise
+ *
+ */
+bool CreateSharedData(const boost::filesystem::path& path,
+                      const std::string& pkgid);
+
+/**
  * \brief Returns path prefix for internal storage, typically '/home'
  *
  * \return path prefix
index fa359d8..b55162b 100644 (file)
@@ -33,7 +33,8 @@ bool StepCreateStorageDirectories::CreatePerUserStorageDirs(
   if (req_type != RequestType::ManifestPartialInstall &&
       req_type != RequestType::ManifestDirectInstall) {
     // remove packaged RW diriectories
-    if (!DeleteStorageDirectories(context_->GetPkgPath())) {
+    if (!DeleteStorageDirectories(context_->root_application_path.get(),
+                                  context_->pkgid.get())) {
       LOG(ERROR) << "Failed to remove storage directories";
       return false;
     }
@@ -57,7 +58,7 @@ bool StepCreateStorageDirectories::CreatePerUserStorageDirs(
 
 bool StepCreateStorageDirectories::CreateStorageDirs(
     bool trusted, bool shareddata) {
-  if (!CreateStorageDirectories(context_->GetPkgPath(),
+  if (!CreateStorageDirectories(context_->root_application_path.get(),
                                 context_->pkgid.get(), context_->uid.get(),
                                 trusted, shareddata)) {
     LOG(ERROR) << "Failed to create storage directories";
index 0d304ba..a36f701 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "common/pkgmgr_query.h"
 #include "common/utils/file_util.h"
+#include "common/shared_dirs.h"
 
 namespace bs = boost::system;
 namespace bf = boost::filesystem;
@@ -107,7 +108,10 @@ Step::Status StepRemoveFiles::process() {
         is_error = true;
     }
   } else {
-    if (!RemoveAll(pkg_path))
+    if (!RemoveAll(pkg_path) ||
+        !common_installer::DeleteSharedDirectories(
+            context_->root_application_path.get(),
+            context_->pkgid.get()))
       is_error = true;
   }
 
index 657a602..fe56a46 100644 (file)
@@ -25,16 +25,6 @@ namespace {
 const char kSharedData[] = "shared/data";
 const char kSkelApp[] = "skel/apps_rw";
 
-bool CreateSharedDir(bf::path shareddir_path) {
-  if (bf::exists(shareddir_path))
-    return true;
-
-  if (!common_installer::CreateDir(shareddir_path))
-    return false;
-
-  return true;
-}
-
 bool RemovePerUserSharedDir(const std::string& pkgid) {
   bf::path shareddir_path = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
       bf::path(kSkelApp) / pkgid / kSharedData;
@@ -95,13 +85,14 @@ bool StepUpdateStorageDirectories::UpdatePerUserStorageDirectories() {
 
 bool StepUpdateStorageDirectories::UpdateStorageDirectories() {
   manifest_x* manifest = context_->manifest_data.get();
-  bf::path shared_data_path = context_->GetPkgPath() / kSharedData;
   if (ShouldCreateSharedDataDir(manifest)) {
-    return CreateSharedDir(shared_data_path);
+    return CreateSharedData(
+        context_->root_application_path.get(), context_->pkgid.get());
   } else {
-    if (!RemoveAll(shared_data_path))
-      return false;
+    return DeleteSharedDirectories(
+        context_->root_application_path.get(), context_->pkgid.get());
   }
+
   return true;
 }
 
index a162be9..1f7f845 100644 (file)
@@ -674,4 +674,43 @@ bool IsSubDir(const boost::filesystem::path& path,
   return false;
 }
 
+bf::path RelativePath(const bf::path& from,
+                                     const bf::path& to) {
+  bf::path::const_iterator itr_path = from.begin();
+  bf::path::const_iterator itr_relative_to = to.begin();
+  while (itr_path != from.end() && itr_relative_to != to.end() &&
+         *itr_path == *itr_relative_to) {
+    ++itr_path;
+    ++itr_relative_to;
+  }
+
+  bf::path result;
+  if (itr_relative_to != to.end()) {
+    ++itr_relative_to;
+    while (itr_relative_to != to.end()) {
+      result /= "..";
+      ++itr_relative_to;
+    }
+  }
+
+  while (itr_path != from.end()) {
+    result /= *itr_path;
+    ++itr_path;
+  }
+
+  bs::error_code error;
+  bf::path resolved_path = bf::canonical(result, error);
+  if (error) {
+    LOG(ERROR) << "Failed to get canonical path";
+    return {};
+  }
+
+  if (from != resolved_path) {
+    LOG(ERROR) << "Failed to get right relative path :" << resolved_path;
+    return {};
+  }
+
+  return result;
+}
+
 }  // namespace common_installer
index 16fd263..20c8a91 100644 (file)
@@ -88,6 +88,9 @@ boost::filesystem::path MakeRelativePath(const boost::filesystem::path& input,
 bool IsSubDir(const boost::filesystem::path& path,
               const boost::filesystem::path& root);
 
+boost::filesystem::path RelativePath(const boost::filesystem::path& from,
+                                     const boost::filesystem::path& to);
+
 }  // namespace common_installer
 
 #endif  // COMMON_UTILS_FILE_UTIL_H_
index 11c49c0..8f62dd9 100644 (file)
@@ -48,6 +48,8 @@ const char kSkelDir[] = "/etc/skel/apps_rw";
 const char kPreloadApps[] = "/usr/apps";
 const char kPreloadManifestDir[] = "/usr/share/packages";
 const char kPreloadIcons[] = "/usr/share/icons";
+const char kShared[] = ".shared";
+const char kSharedTmp[] = ".shared_tmp";
 
 enum RWDirectory {
   DATA,
@@ -452,9 +454,13 @@ bool CheckPackageNonExistance(const std::string& pkgid,
   if (params.test_user.uid == kGlobalUserUid) {
     bf::path skel_path(kSkelDir);
     EXTENDED_ASSERT_FALSE(bf::exists(skel_path / pkgid));
+    EXTENDED_ASSERT_FALSE(bf::exists(skel_path / kShared / pkgid));
+    EXTENDED_ASSERT_FALSE(bf::exists(skel_path / kSharedTmp / pkgid));
     ci::UserList list = ci::GetUserList();
     for (auto& l : list) {
       bf::path root_path = ci::GetRootAppPath(false, std::get<0>(l));
+      EXTENDED_ASSERT_FALSE(bf::exists(root_path / kShared / pkgid));
+      EXTENDED_ASSERT_FALSE(bf::exists(root_path / kSharedTmp / pkgid));
       bf::path package_path = root_path / pkgid;
       EXTENDED_ASSERT_FALSE(bf::exists(package_path));
     }