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 <[email protected]> --- 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; - + } /* -- AppArmor mailing list [email protected] Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor
