[apparmor] RFC [patch 7/10] Hack rework of the feature/match file support

John Johansen john.johansen at canonical.com
Thu Feb 13 01:03:17 UTC 2014


Hack rework of the feature/match file support

This is not the cleanup this code needs, but a quick hack to add the
-M flag so we can specify a feature file (or directory) to use for
the compile.

It mostly just moves around existing code and adds the -M option,
though it does introduce a few changes.

While I didn't do it in this patch I propose we drop support for
the match file without create support. This is several years old
now and would clean things up a lot.

Note: that the manually input -m or -M drop support for it already
I just can't see a good way to support a single input stream indicating
the result/existance of two separate files.

This needs more work but is needed to support tests and the policy_mediates
frame work depends on the policydb getting generated with the special
stub rules to indicate whether policy was compiled expecting a certain
feature. But this can break the current tests, at least once a bug
in the policy rule counting is fixed in a follow on patch.

Signed-off-by: John Johansen <john.johansen at canonical.com>

---
 parser/parser_main.c |  104 +++++++++++++++++++++++++--------------------------
 1 file changed, 52 insertions(+), 52 deletions(-)

--- 2.9-test.orig/parser/parser_main.c
+++ 2.9-test/parser/parser_main.c
@@ -53,7 +53,7 @@
 #define OLD_MODULE_NAME "subdomain"
 #define PROC_MODULES "/proc/modules"
 #define DEFAULT_APPARMORFS "/sys/kernel/security/" MODULE_NAME
-#define MATCH_STRING "/sys/kernel/security/" MODULE_NAME "/matching"
+#define MATCH_FILE "/sys/kernel/security/" MODULE_NAME "/matching"
 #define FLAGS_FILE "/sys/kernel/security/" MODULE_NAME "/features"
 #define MOUNTED_FS "/proc/mounts"
 #define AADFA "pattern=aadfa"
@@ -80,15 +80,17 @@
 struct timespec mru_tstamp;
 
 #define FLAGS_STRING_SIZE 8192
-char *match_string = NULL;
 char *flags_string = NULL;
 char *cacheloc = NULL;
 
 /* per-profile settings */
 int force_complain = 0;
 
+static void get_flags_string(char **flags, const char *flags_file);
+static void load_features(const char *name);
+
 /* Make sure to update BOTH the short and long_options */
-static const char *short_options = "adf:h::rRVvI:b:BCD:NSm:qQn:XKTWkL:O:po:";
+static const char *short_options = "adf:h::rRVvI:b:BCD:NSm:M:qQn:XKTWkL:O:po:";
 struct option long_options[] = {
 	{"add", 		0, 0, 'a'},
 	{"binary",		0, 0, 'B'},
@@ -106,6 +108,7 @@
 	{"stdout",		0, 0, 'S'},
 	{"ofile",		1, 0, 'o'},
 	{"match-string",	1, 0, 'm'},
+	{"features-file",	1, 0, 'M'},
 	{"quiet",		0, 0, 'q'},
 	{"skip-kernel-load",	0, 0, 'Q'},
 	{"verbose",		0, 0, 'v'},
@@ -520,7 +523,10 @@
 		}
 		break;
 	case 'm':
-		match_string = strdup(optarg);
+		flags_string = strdup(optarg);
+		break;
+	case 'M':
+		load_features(optarg);
 		break;
 	case 'q':
 		conf_verbose = 0;
@@ -740,64 +746,63 @@
 	return fst.pos;
 }
 
-/* match_string == NULL --> no match_string available
-   match_string != NULL --> either a matching string specified on the
-   command line, or the kernel supplied a match string */
-static void get_match_string(void) {
-
+static void load_features(const char *name)
+{
 	FILE *ms = NULL;
 	struct stat stat_file;
 
-	/* has process_args() already assigned a match string? */
-	if (match_string)
-		goto out;
-
 	if (stat(FLAGS_FILE, &stat_file) == -1)
 		goto out;
 
 	if (S_ISDIR(stat_file.st_mode)) {
 		/* if we have a features directory default to */
-		perms_create = 1;
-
 		flags_string = (char *) malloc(FLAGS_STRING_SIZE);
-		handle_features_dir(FLAGS_FILE, &flags_string, FLAGS_STRING_SIZE, flags_string);
-		if (strstr(flags_string, "network"))
-			kernel_supports_network = 1;
-		else
-			kernel_supports_network = 0;
-		if (strstr(flags_string, "mount"))
-			kernel_supports_mount = 1;
-		if (strstr(flags_string, "dbus"))
-			kernel_supports_dbus = 1;
+		handle_features_dir(name, &flags_string, FLAGS_STRING_SIZE, flags_string);
+		perms_create = 1;
 		return;
-	}
-
-	ms = fopen(MATCH_STRING, "r");
-	if (!ms)
-		goto out;
+	} else
+		get_flags_string(&flags_string, name);
 
-	match_string = (char *) malloc(1000);
-	if (!match_string) {
-		goto out;
-	}
-
-	if (!fgets(match_string, 1000, ms)) {
-		free(match_string);
-		match_string = NULL;
-	}
 
-out:
-	if (match_string) {
+	ms = fopen(MATCH_FILE, "r");
+	if (ms) {
+		char *match_string = (char *) malloc(1000);
+		if (!match_string)
+			goto no_match;
+		if (!fgets(match_string, 1000, ms)) {
+			free(match_string);
+			goto no_match;
+		}
 		if (strstr(match_string, " perms=c"))
 			perms_create = 1;
-	} else {
-		perms_create = 1;
-		kernel_supports_network = 0;
+		free(match_string);
+		goto out;
 	}
+no_match:
+	perms_create = 1;
+	kernel_supports_network = 0;
 
+out:
 	if (ms)
 		fclose(ms);
-	return;
+}
+
+/* match_string == NULL --> no match_string available
+   match_string != NULL --> either a matching string specified on the
+   command line, or the kernel supplied a match string */
+static void set_supported_flags(void) {
+
+	/* has process_args() already assigned a match string? */
+	if (!flags_string)
+		load_features(FLAGS_FILE);
+
+	/* TODO: make this real parsing and config setting */
+	if (strstr(flags_string, "network"))
+		kernel_supports_network = 1;
+	if (strstr(flags_string, "mount"))
+		kernel_supports_mount = 1;
+	if (strstr(flags_string, "dbus"))
+		kernel_supports_dbus = 1;
 }
 
 static void get_flags_string(char **flags, const char *flags_file) {
@@ -1211,9 +1216,8 @@
 	char *cache_flags = NULL;
 
 	/* Get the match string to determine type of regex support needed */
-	get_match_string();
-	/* Get kernel features string */
-	get_flags_string(&flags_string, FLAGS_FILE);
+	set_supported_flags();
+
 	/* Gracefully handle AppArmor kernel without compatibility patch */
 	if (!flags_string) {
 		PERROR("Cache read/write disabled: %s interface file missing. "
@@ -1222,11 +1226,7 @@
 		write_cache = 0;
 		skip_read_cache = 1;
 		return;
-	} else if (strstr(flags_string, "network"))
-		kernel_supports_network = 1;
-	else
-		kernel_supports_network = 0;
-
+	}
 
 
 	/*




More information about the AppArmor mailing list