apparmor: prepare to support newer versions of policy
authorJohn Johansen <john.johansen@canonical.com>
Mon, 16 Jan 2017 08:42:39 +0000 (00:42 -0800)
committerJohn Johansen <john.johansen@canonical.com>
Mon, 16 Jan 2017 09:18:32 +0000 (01:18 -0800)
Newer policy encodes more than just version in the version tag,
so add masking to make sure the comparison remains correct.

Note: this is fully compatible with older policy as it will never set
the bits being masked out.

Signed-off-by: John Johansen <john.johansen@canonical.com>
security/apparmor/apparmorfs.c
security/apparmor/policy_unpack.c

index 2b48be2169cb36cabf5f4d6887bf0b27a1fbb13c..49a5122e03fe22f378ea7efb5e804db90dbebea4 100644 (file)
@@ -799,9 +799,15 @@ static struct aa_fs_entry aa_fs_entry_domain[] = {
        { }
 };
 
+static struct aa_fs_entry aa_fs_entry_versions[] = {
+       AA_FS_FILE_BOOLEAN("v5",        1),
+       { }
+};
+
 static struct aa_fs_entry aa_fs_entry_policy[] = {
-       AA_FS_FILE_BOOLEAN("set_load",          1),
-       {}
+       AA_FS_DIR("versions",                   aa_fs_entry_versions),
+       AA_FS_FILE_BOOLEAN("set_load",          1),
+       { }
 };
 
 static struct aa_fs_entry aa_fs_entry_features[] = {
index c836a9c8b6ff515dee7e71c81f59aa5b54733984..6ac292fec55f9d1f1b17b82cc694039848a79146 100644 (file)
 #include "include/policy.h"
 #include "include/policy_unpack.h"
 
+#define K_ABI_MASK 0x3ff
 #define FORCE_COMPLAIN_FLAG 0x800
+#define VERSION_LT(X, Y) (((X) & K_ABI_MASK) < ((Y) & K_ABI_MASK))
+#define VERSION_GT(X, Y) (((X) & K_ABI_MASK) > ((Y) & K_ABI_MASK))
+
+#define v5     5       /* base version */
+#define v6     6       /* per entry policydb mediation check */
+#define v7     7       /* full network masking */
 
 /*
  * The AppArmor interface treats data as a type byte followed by the
@@ -646,19 +653,21 @@ static int verify_header(struct aa_ext *e, int required, const char **ns)
        /* get the interface version */
        if (!unpack_u32(e, &e->version, "version")) {
                if (required) {
-                       audit_iface(NULL, NULL, "invalid profile format", e,
-                                   error);
-                       return error;
-               }
-
-               /* check that the interface version is currently supported */
-               if (e->version != 5) {
-                       audit_iface(NULL, NULL, "unsupported interface version",
+                       audit_iface(NULL, NULL, "invalid profile format",
                                    e, error);
                        return error;
                }
        }
 
+       /* Check that the interface version is currently supported.
+        * if not specified use previous version
+        * Mask off everything that is not kernel abi version
+        */
+       if (VERSION_LT(e->version, v5) && VERSION_GT(e->version, v7)) {
+               audit_iface(NULL, NULL, "unsupported interface version",
+                           e, error);
+               return error;
+       }
 
        /* read the namespace if present */
        if (unpack_str(e, &name, "namespace")) {