CHROMIUM: relabel some fs at init start.

devtmpfs is created by kernel before SELinux loads. Kernel has no
context about SELinux, thus /dev is having wrong file contexts for
individually labelled file.

init should re-label existing file in /dev to make sure it has the right
contexts.

Currently, NYC didn't combine with CrOS policies, so re-labeling it will
lead to EPERM. We silently ignore the errors occurred during restorecon
for now. This should be fixed once everything has CrOS policies
combined.

BUG=b:69139821
TEST=build_images with kevin and kevin-arcnext

Reviewed-on: https://chromium-review.googlesource.com/1140022
Change-Id: I0351579ec83260022c252aebb7c7d411990c6fb3
diff --git a/configure.ac b/configure.ac
index a814437..404c5ca 100644
--- a/configure.ac
+++ b/configure.ac
@@ -75,6 +75,7 @@
 if test "x$enable_selinux" = "xyes" ; then
 	PKG_CHECK_MODULES(SELINUX, [libselinux])
 	AC_DEFINE(HAVE_SELINUX, 1, [Define if we have SELinux])
+	AC_DEFINE(RESTORE_PATHS, [{"/dev"}], [Define restorecon paths])
 fi
 
 # Checks for typedefs, structures, and compiler characteristics.
diff --git a/init/main.c b/init/main.c
index ed3ee6b..9325ce9 100644
--- a/init/main.c
+++ b/init/main.c
@@ -49,6 +49,7 @@
 
 #ifdef HAVE_SELINUX
 #include <selinux/selinux.h>
+#include <selinux/restorecon.h>
 #endif
 
 #include <linux/kd.h>
@@ -282,6 +283,20 @@
 			exit (1);
 		}
 
+               const char *restore_paths[] = RESTORE_PATHS;
+               for (size_t i = 0;
+		     i < sizeof(restore_paths) / sizeof(const char *);
+		     i++) {
+			const int restorecon_args = SELINUX_RESTORECON_RECURSE |
+						    SELINUX_RESTORECON_REALPATH;
+       	        if (selinux_restorecon(restore_paths[i],
+					       restorecon_args) != 0) {
+				nih_warn ("%s: %d",
+					  _("Failed to restorecon"), errno);
+				// ignore error for now until policy are combined. exit(1);
+			}
+               }
+
 		putenv ("SELINUX_INIT=YES");
 		nih_info (_("SELinux policy loaded, doing self-exec"));