checkfc: validate that all rules are matching
For the file backend, libselinux keeps track of which rules has matched.
Set up the callback and capture any log message from selinux_stats. If,
at least one rule has not been used, exit with the status code 1.
Bug: 299839280
Test: checkfc -t ./private/file_contexts ./tests/plat_file_contexts_test
Change-Id: I33d88b4234756cd13e29c5c8c081d97b6590810e
diff --git a/tools/checkfc.c b/tools/checkfc.c
index 05826f9..051e24b 100644
--- a/tools/checkfc.c
+++ b/tools/checkfc.c
@@ -271,6 +271,19 @@
printf("%s\n", result_str[result]);
}
+static int warnings = 0;
+static int log_callback(int type, const char *fmt, ...) {
+ va_list ap;
+
+ if (type == SELINUX_WARNING) {
+ warnings += 1;
+ }
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ return 0;
+}
+
static void do_test_data_and_die_on_error(struct selinux_opt opts[], unsigned int backend,
char *paths[])
{
@@ -329,7 +342,15 @@
// Prints the coverage of file_contexts on the test data. It includes
// warnings for rules that have not been hit by any test example.
+ union selinux_callback cb;
+ cb.func_log = log_callback;
+ selinux_set_callback(SELINUX_CB_LOG, cb);
selabel_stats(global_state.sepolicy.sehnd[0]);
+ if (warnings) {
+ fprintf(stderr, "No test entries were found for the contexts above. " \
+ "You may need to update %s.\n", paths[1]);
+ exit(1);
+ }
}
static void do_fc_check_and_die_on_error(struct selinux_opt opts[], unsigned int backend, filemode mode,