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

Reply via email to