Set write/setgid bit on data, shared/data dir 42/100642/2 accepted/tizen/3.0/common/20161130.133553 accepted/tizen/3.0/ivi/20161130.091212 accepted/tizen/3.0/mobile/20161130.091112 accepted/tizen/3.0/tv/20161130.091140 accepted/tizen/3.0/wearable/20161130.091157 submit/tizen_3.0/20161130.023420
authorSangyoon Jang <s89.jang@samsung.com>
Tue, 29 Nov 2016 00:50:20 +0000 (09:50 +0900)
committerSangyoon Jang <s89.jang@samsung.com>
Tue, 29 Nov 2016 04:34:11 +0000 (20:34 -0800)
System daemons who want to access data, shared/data need
CAP_DAC_OVERRIDE, but this cap gives unwanted permissions too much.
So we modify permission bits of writable directories and
make available for system daemons with minimum permission.

Change-Id: I8b53e60686cffa56c0be838312bc16859bc6ee5c
Signed-off-by: Sangyoon Jang <s89.jang@samsung.com>
src/common/shared_dirs.cc
src/common/step/filesystem/step_change_owner.cc

index b83e35e..a5b59f8 100644 (file)
@@ -55,9 +55,9 @@ const utils::VersionNumber ver30("3.0");
 
 const std::vector<const char*> kEntries = {
   {"/"},
-  {"cache/"},
-  {"data/"},
-  {"shared/"},
+  {"cache"},
+  {"data"},
+  {"shared"},
 };
 const std::vector<const char*> kReadOnlyEntries = {
   {"bin"},
@@ -72,6 +72,7 @@ const char kSharedTrustedDir[] = "shared/trusted";
 const char kSkelAppDir[] = "/etc/skel/apps_rw";
 const char kExternalStoragePrivilege[] =
     "http://tizen.org/privilege/externalstorage.appdata";
+const char kSystemShareGroupName[] = "system_share";
 
 bool SetFileOwner(const bf::path& subpath, uid_t uid, gid_t gid) {
   bs::error_code error;
@@ -118,6 +119,14 @@ bool SetPackageDirectoryOwnerAndPermissions(const bf::path& subpath, uid_t uid,
   bool result = true;
   if (bf::is_directory(subpath)) {
     perms |= bf::owner_exe | bf::group_exe | bf::others_exe;
+    if (subpath.filename() == "data") {
+      perms |= bf::group_write | bf::set_gid_on_exe;
+      boost::optional<gid_t> system_share =
+          ci::GetGidByGroupName(kSystemShareGroupName);
+      if (!system_share)
+        return false;
+      gid = *system_share;
+    }
     result = SetOwnerAndPermissions(subpath, uid, gid, perms);
   }
 
index 5c90ebf..7041e69 100644 (file)
@@ -16,6 +16,7 @@
 #include <vector>
 
 #include "common/paths.h"
+#include "common/request.h"
 #include "common/shared_dirs.h"
 #include "common/utils/file_util.h"
 #include "common/utils/glist_range.h"
 namespace bf = boost::filesystem;
 namespace ci = common_installer;
 
+namespace {
+
+const char kSystemShareGroupName[] = "system_share";
+const char kDataDir[] = "data";
+const char kSharedDataDir[] = "shared/data";
+
+bool ChangeDataDir(const bf::path& pkg_path, uid_t uid) {
+  if (ci::GetRequestMode(uid) == ci::RequestMode::GLOBAL)
+    return true;
+  boost::optional<gid_t> gid = ci::GetGidByGroupName(kSystemShareGroupName);
+  if (!gid) {
+    LOG(ERROR) << "Failed to get gid of " << kSystemShareGroupName;
+    return false;
+  }
+
+  bf::perms prms = bf::add_perms | bf::group_write | bf::group_exe |
+                   bf::set_gid_on_exe;
+  bf::path data = pkg_path / kDataDir;
+  if (!ci::SetOwnership(data, uid, *gid)) {
+    LOG(ERROR) << "Failed to change owner: " << data
+               << "(" << uid << ", " << *gid << ")";
+    return false;
+  }
+  if (!ci::SetDirPermissions(data, prms)) {
+    LOG(ERROR) << "Failed to change permission: " << data
+               << std::oct << prms;
+    return false;
+  }
+  bf::path shareddata = pkg_path / kSharedDataDir;
+  if (!bf::exists(shareddata))
+    return true;
+  if (!ci::SetOwnership(shareddata, uid, *gid)) {
+    LOG(ERROR) << "Failed to change owner: " << shareddata
+               << "(" << uid << ", " << *gid << ")";
+    return false;
+  }
+  if (!ci::SetDirPermissions(shareddata, prms)) {
+    LOG(ERROR) << "Failed to change permission: " << shareddata
+               << std::oct << prms;
+    return false;
+  }
+
+  return true;
+}
+
+}  // namespace
+
 namespace common_installer {
 namespace filesystem {
 
@@ -58,6 +106,9 @@ Step::Status StepChangeOwner::process() {
   if (!ci::SetOwnershipAll(context_->pkg_path.get(), uid, *gid))
     return Status::ERROR;
 
+  if (!ChangeDataDir(context_->pkg_path.get(), uid))
+    return Status::ERROR;
+
   // For icon files
   const char *iconpath = getIconPath(uid, context_->is_readonly_package.get());
   if (iconpath) {