OSDN Git Service

Don't resolve permitted.paths
authorJiyong Park <jiyong@google.com>
Thu, 21 Sep 2017 01:27:36 +0000 (10:27 +0900)
committerJiyong Park <jiyong@google.com>
Thu, 21 Sep 2017 02:48:06 +0000 (11:48 +0900)
Linker resolves the paths in /system/etc/ld.config.txt to canonicalize
the paths and to ensure they exist. However, as permitted paths for the
default namespace contain directories such as /vendor/app, /mnt/expand,
and etc., the resolving causes selinux denial on some processes which do
not have access to some of the permitted paths.

In order to silence the bogus selinux denial, resolution is skipped for
permitted paths.

Note that the resolution is not strictly required especially for
Treble-ized devices where permitted paths are already canonicalized (i.e
/vendor isn't a symlink to /system/vendor).

Bug: 65843095
Test: no selinux denial on /vendor/app, /vendor/framework, etc. while
booting.

Change-Id: I1a9921e45f4c15b08cdf8f1caee64c4cb0761e1f

linker/linker_config.cpp

index 0a9aeab..e036c05 100644 (file)
@@ -320,7 +320,7 @@ class Properties {
     return (it == properties_.end()) ? "" : it->second.value();
   }
 
-  std::vector<std::string> get_paths(const std::string& name, size_t* lineno = nullptr) {
+  std::vector<std::string> get_paths(const std::string& name, bool resolve, size_t* lineno = nullptr) {
     std::string paths_str = get_string(name, lineno);
 
     std::vector<std::string> paths;
@@ -338,12 +338,16 @@ class Properties {
       format_string(&path, params);
     }
 
-    std::vector<std::string> resolved_paths;
+    if (resolve) {
+      std::vector<std::string> resolved_paths;
 
-    // do not remove paths that do not exist
-    resolve_paths(paths, &resolved_paths);
+      // do not remove paths that do not exist
+      resolve_paths(paths, &resolved_paths);
 
-    return resolved_paths;
+      return resolved_paths;
+    } else {
+      return paths;
+    }
   }
 
   void set_target_sdk_version(int target_sdk_version) {
@@ -465,8 +469,18 @@ bool Config::read_binary_config(const char* ld_config_file_path,
       property_name_prefix += ".asan";
     }
 
-    ns_config->set_search_paths(properties.get_paths(property_name_prefix + ".search.paths"));
-    ns_config->set_permitted_paths(properties.get_paths(property_name_prefix + ".permitted.paths"));
+    // search paths are resolved (canonicalized). This is required mainly for
+    // the case when /vendor is a symlink to /system/vendor, which is true for
+    // non Treble-ized legacy devices.
+    ns_config->set_search_paths(properties.get_paths(property_name_prefix + ".search.paths", true));
+
+    // However, for permitted paths, we are not required to resolve the paths
+    // since they are only set for isolated namespaces, which implies the device
+    // is Treble-ized (= /vendor is not a symlink to /system/vendor).
+    // In fact, the resolving is causing an unexpected side effect of selinux
+    // denials on some executables which are not allowed to access some of the
+    // permitted paths.
+    ns_config->set_permitted_paths(properties.get_paths(property_name_prefix + ".permitted.paths", false));
   }
 
   failure_guard.Disable();