Add BOARD_GENFS_LABELS_VERSION

If it's 202504 or later, /sys/class/udc will be labeled as sysfs_udc. If
it's not set, /sys/class/udc will stay at the label sysfs. This is to
support GRF vendors older than 202504.

202404 or old vendors can choose either way. If they want to customize
permissions to /sys/class/udc, they can turn off
BOARD_GENFS_LABELS_VERSION and assign their own label to /sys/class/udc
/sys/class/udc with vendor sepolicy.

202504 or newer vendors must set BOARD_GENFS_LABELS_VERSION to a version
greater than or equal to 202504.

For now there's only one node /sys/class/udc, but more labels can be
added until 202504 freeze.

Bug: 361985697
Test: boot with and without BOARD_GENFS_LABELS_VERSION
Change-Id: I1a28109119368f1475628be85dd8d990c824922e
diff --git a/init/selinux.cpp b/init/selinux.cpp
index c2d9b8d..5ced0b8 100644
--- a/init/selinux.cpp
+++ b/init/selinux.cpp
@@ -190,6 +190,22 @@
     return true;
 }
 
+int GetVendorGenfsVersion() {
+    std::string line;
+    if (!ReadFirstLine("/vendor/etc/selinux/genfs_labels_version.txt", &line)) {
+        PLOG(ERROR) << "Failed to read /vendor/etc/selinux/genfs_labels_version.txt; assuming it's "
+                       "202404";
+        return 202404;
+    }
+    int version;
+    if (!ParseInt(line, &version)) {
+        PLOG(ERROR) << "Failed to parse the genfs labels version " << line
+                    << "; assuming it's 202404";
+        return 202404;
+    }
+    return version;
+}
+
 constexpr const char plat_policy_cil_file[] = "/system/etc/selinux/plat_sepolicy.cil";
 
 bool IsSplitPolicyDevice() {
@@ -324,6 +340,15 @@
     }
     const std::string version_as_string = std::to_string(SEPOLICY_VERSION);
 
+    std::vector<std::string> genfs_cil_files;
+
+    int vendor_genfs_version = GetVendorGenfsVersion();
+    std::string genfs_cil_file =
+            std::format("/system/etc/selinux/plat_sepolicy_genfs_{}.cil", vendor_genfs_version);
+    if (access(genfs_cil_file.c_str(), F_OK) != 0) {
+        genfs_cil_file.clear();
+    }
+
     // clang-format off
     std::vector<const char*> compile_args {
         "/system/bin/secilc",
@@ -364,6 +389,9 @@
     if (!odm_policy_cil_file.empty()) {
         compile_args.push_back(odm_policy_cil_file.c_str());
     }
+    if (!genfs_cil_file.empty()) {
+        compile_args.push_back(genfs_cil_file.c_str());
+    }
     compile_args.push_back(nullptr);
 
     if (!ForkExecveAndWaitForCompletion(compile_args[0], (char**)compile_args.data())) {