Add a checkfc utility to check file_contexts validity and invoke it.
Change-Id: I4b12dc3dcb432edbdf95dd3bc97f809912ce86d1
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
diff --git a/Android.mk b/Android.mk
index 2c93c63..2d06c03 100644
--- a/Android.mk
+++ b/Android.mk
@@ -45,6 +45,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)
@@ -55,10 +68,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);
+}