Merge "enable fuzzing trusty targets automatically"
diff --git a/init/selinux.cpp b/init/selinux.cpp
index 0336936..47686b8 100644
--- a/init/selinux.cpp
+++ b/init/selinux.cpp
@@ -92,7 +92,7 @@
 
 enum EnforcingStatus { SELINUX_PERMISSIVE, SELINUX_ENFORCING };
 
-EnforcingStatus StatusFromCmdline() {
+EnforcingStatus StatusFromProperty() {
     EnforcingStatus status = SELINUX_ENFORCING;
 
     ImportKernelCmdline([&](const std::string& key, const std::string& value) {
@@ -101,12 +101,20 @@
         }
     });
 
+    if (status == SELINUX_ENFORCING) {
+        ImportBootconfig([&](const std::string& key, const std::string& value) {
+            if (key == "androidboot.selinux" && value == "permissive") {
+                status = SELINUX_PERMISSIVE;
+            }
+        });
+    }
+
     return status;
 }
 
 bool IsEnforcing() {
     if (ALLOW_PERMISSIVE_SELINUX) {
-        return StatusFromCmdline() == SELINUX_ENFORCING;
+        return StatusFromProperty() == SELINUX_ENFORCING;
     }
     return true;
 }
diff --git a/init/util.cpp b/init/util.cpp
index eab99d4..a40d104 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -376,6 +376,15 @@
             android_dt_dir = value;
         }
     });
+    // ..Or bootconfig
+    if (android_dt_dir == kDefaultAndroidDtDir) {
+        ImportBootconfig([&](const std::string& key, const std::string& value) {
+            if (key == "androidboot.android_dt_dir") {
+                android_dt_dir = value;
+            }
+        });
+    }
+
     LOG(INFO) << "Using Android DT directory " << android_dt_dir;
     return android_dt_dir;
 }
diff --git a/libprocessgroup/cgrouprc/include/android/cgrouprc.h b/libprocessgroup/cgrouprc/include/android/cgrouprc.h
index 9a79954..100d60e 100644
--- a/libprocessgroup/cgrouprc/include/android/cgrouprc.h
+++ b/libprocessgroup/cgrouprc/include/android/cgrouprc.h
@@ -68,6 +68,7 @@
  */
 #define CGROUPRC_CONTROLLER_FLAG_MOUNTED 0x1
 #define CGROUPRC_CONTROLLER_FLAG_NEEDS_ACTIVATION 0x2
+#define CGROUPRC_CONTROLLER_FLAG_OPTIONAL 0x4
 
 /**
  * Returns the flags bitmask of the given controller.
diff --git a/libprocessgroup/profiles/cgroups.json b/libprocessgroup/profiles/cgroups.json
index 962d2ba..0634220 100644
--- a/libprocessgroup/profiles/cgroups.json
+++ b/libprocessgroup/profiles/cgroups.json
@@ -26,7 +26,8 @@
       "Path": "/dev/memcg",
       "Mode": "0700",
       "UID": "root",
-      "GID": "system"
+      "GID": "system",
+      "Optional": true
     }
   ],
   "Cgroups2": {
diff --git a/libprocessgroup/profiles/cgroups.proto b/libprocessgroup/profiles/cgroups.proto
index 13adcae..f2de345 100644
--- a/libprocessgroup/profiles/cgroups.proto
+++ b/libprocessgroup/profiles/cgroups.proto
@@ -24,7 +24,7 @@
     Cgroups2 cgroups2 = 2 [json_name = "Cgroups2"];
 }
 
-// Next: 7
+// Next: 8
 message Cgroup {
     string controller = 1 [json_name = "Controller"];
     string path = 2 [json_name = "Path"];
@@ -35,6 +35,7 @@
 // when a boolean is specified as false, so leave unspecified in that case
 // https://developers.google.com/protocol-buffers/docs/proto3#default
     bool needs_activation = 6 [json_name = "NeedsActivation"];
+    bool is_optional = 7 [json_name = "Optional"];
 }
 
 // Next: 6
diff --git a/libprocessgroup/profiles/cgroups_30.json b/libprocessgroup/profiles/cgroups_30.json
index 17d4929..80a074b 100644
--- a/libprocessgroup/profiles/cgroups_30.json
+++ b/libprocessgroup/profiles/cgroups_30.json
@@ -5,7 +5,8 @@
       "Path": "/dev/stune",
       "Mode": "0755",
       "UID": "system",
-      "GID": "system"
+      "GID": "system",
+      "Optional": true
     }
   ]
 }
diff --git a/libprocessgroup/setup/cgroup_map_write.cpp b/libprocessgroup/setup/cgroup_map_write.cpp
index b0b91f8..3121d24 100644
--- a/libprocessgroup/setup/cgroup_map_write.cpp
+++ b/libprocessgroup/setup/cgroup_map_write.cpp
@@ -161,6 +161,10 @@
         controller_flags |= CGROUPRC_CONTROLLER_FLAG_NEEDS_ACTIVATION;
     }
 
+    if (cgroup["Optional"].isBool() && cgroup["Optional"].asBool()) {
+        controller_flags |= CGROUPRC_CONTROLLER_FLAG_OPTIONAL;
+    }
+
     CgroupDescriptor descriptor(
             cgroups_version, name, path, std::strtoul(cgroup["Mode"].asString().c_str(), 0, 8),
             cgroup["UID"].asString(), cgroup["GID"].asString(), controller_flags);
@@ -308,8 +312,15 @@
     }
 
     if (result < 0) {
-        PLOG(ERROR) << "Failed to mount " << controller->name() << " cgroup";
-        return false;
+        bool optional = controller->flags() & CGROUPRC_CONTROLLER_FLAG_OPTIONAL;
+
+        if (optional && errno == EINVAL) {
+            // Optional controllers are allowed to fail to mount if kernel does not support them
+            LOG(INFO) << "Optional " << controller->name() << " cgroup controller is not mounted";
+        } else {
+            PLOG(ERROR) << "Failed to mount " << controller->name() << " cgroup";
+            return false;
+        }
     }
 
     return true;