am 01a58af1: Add a checkfc utility to check file_contexts validity and invoke it.

* commit '01a58af19494420bb259505bc5404790a21fdd64':
  Add a checkfc utility to check file_contexts validity and invoke it.
diff --git a/Android.mk b/Android.mk
index a46a00b..6f5d5c6 100644
--- a/Android.mk
+++ b/Android.mk
@@ -58,6 +58,19 @@
 	$(hide) $(HOST_OUT_EXECUTABLES)/checkpolicy -M -c $(POLICYVERS) -o $@ $<
 
 sepolicy_policy.conf :=
+
+###################################
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := checkfc
+LOCAL_MODULE_TAGS := optional
+LOCAL_C_INCLUDES += external/libsepol/include external/libselinux/include
+LOCAL_SRC_FILES := checkfc.c
+LOCAL_STATIC_LIBRARIES := libsepol libselinux
+LOCAL_MODULE_CLASS := EXECUTABLES
+
+include $(BUILD_HOST_EXECUTABLE)
+
 ##################################
 include $(CLEAR_VARS)
 
@@ -68,10 +81,13 @@
 
 include $(BUILD_SYSTEM)/base_rules.mk
 
+ALL_FC_FILES := $(LOCAL_PATH)/file_contexts $(LOCAL_POLICY_FC)
+
 file_contexts := $(intermediates)/file_contexts
-$(file_contexts): $(LOCAL_PATH)/file_contexts $(LOCAL_POLICY_FC)
+$(file_contexts):  $(ALL_FC_FILES) sepolicy $(HOST_OUT_EXECUTABLES)/checkfc
 	@mkdir -p $(dir $@)
-	$(hide) m4 -s $^ > $@
+	$(hide) m4 -s $(ALL_FC_FILES) > $@
+	$(hide) $(HOST_OUT_EXECUTABLES)/checkfc $(TARGET_ROOT_OUT)/sepolicy $@
 
 file_contexts :=
 
diff --git a/checkfc.c b/checkfc.c
new file mode 100644
index 0000000..4be3216
--- /dev/null
+++ b/checkfc.c
@@ -0,0 +1,58 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sepol/sepol.h>
+#include <selinux/selinux.h>
+#include <selinux/label.h>
+
+static int nerr;
+
+static int validate(char **contextp)
+{
+  char *context = *contextp;
+  if (sepol_check_context(context) < 0) {
+    nerr++;
+    return -1;
+  }
+  return 0;
+}
+
+int main(int argc, char **argv)
+{
+  struct selinux_opt opts[] = {
+    { SELABEL_OPT_VALIDATE, (void*)1 },
+    { SELABEL_OPT_PATH, NULL }
+  };
+  FILE *fp;
+  struct selabel_handle *sehnd;
+
+  if (argc != 3) {
+    fprintf(stderr, "usage:  %s policy file_contexts\n", argv[0]);
+    exit(1);
+  }
+
+  fp = fopen(argv[1], "r");
+  if (!fp) {
+    perror(argv[1]);
+    exit(2);
+  }
+  if (sepol_set_policydb_from_file(fp) < 0) {
+    fprintf(stderr, "Error loading policy from %s\n", argv[1]);
+    exit(3);
+  }
+
+  selinux_set_callback(SELINUX_CB_VALIDATE,
+                       (union selinux_callback)&validate);
+
+
+  opts[1].value = argv[2];
+  sehnd = selabel_open(SELABEL_CTX_FILE, opts, 2);
+  if (!sehnd) {
+    fprintf(stderr, "Error loading file contexts from %s\n", argv[2]);
+    exit(4);
+  }
+  if (nerr) {
+    fprintf(stderr, "Invalid file contexts found in %s\n", argv[2]);
+    exit(5);
+  }
+  exit(0);
+}