]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blobdiff - security/integrity/ima/ima_policy.c
UBUNTU: SAUCE: LSM: Create and manage the lsmblob data structure.
[mirror_ubuntu-jammy-kernel.git] / security / integrity / ima / ima_policy.c
index 87b9b71cb8201ab7840120da7f7241d30cfbbb35..d85f2cf48e2c9fb694d2ec47ac1b5810cb87a060 100644 (file)
@@ -84,7 +84,7 @@ struct ima_rule_entry {
        int pcr;
        unsigned int allowed_algos; /* bitfield of allowed hash algorithms */
        struct {
-               void *rule;     /* LSM file metadata specific */
+               void *rules[LSMBLOB_ENTRIES]; /* LSM file metadata specific */
                char *args_p;   /* audit value */
                int type;       /* audit type */
        } lsm[MAX_LSM_RULES];
@@ -94,6 +94,22 @@ struct ima_rule_entry {
        struct ima_template_desc *template;
 };
 
+/**
+ * ima_lsm_isset - Is a rule set for any of the active security modules
+ * @rules: The set of IMA rules to check.
+ *
+ * If a rule is set for any LSM return true, otherwise return false.
+ */
+static inline bool ima_lsm_isset(void *rules[])
+{
+       int i;
+
+       for (i = 0; i < LSMBLOB_ENTRIES; i++)
+               if (rules[i])
+                       return true;
+       return false;
+}
+
 /*
  * sanity check in case the kernels gains more hash algorithms that can
  * fit in an unsigned int
@@ -347,9 +363,11 @@ static void ima_free_rule_opt_list(struct ima_rule_opt_list *opt_list)
 static void ima_lsm_free_rule(struct ima_rule_entry *entry)
 {
        int i;
+       int r;
 
        for (i = 0; i < MAX_LSM_RULES; i++) {
-               ima_filter_rule_free(entry->lsm[i].rule);
+               for (r = 0; r < LSMBLOB_ENTRIES; r++)
+                       ima_filter_rule_free(entry->lsm[i].rules);
                kfree(entry->lsm[i].args_p);
        }
 }
@@ -400,8 +418,8 @@ static struct ima_rule_entry *ima_lsm_copy_rule(struct ima_rule_entry *entry)
 
                ima_filter_rule_init(nentry->lsm[i].type, Audit_equal,
                                     nentry->lsm[i].args_p,
-                                    &nentry->lsm[i].rule);
-               if (!nentry->lsm[i].rule)
+                                    &nentry->lsm[i].rules[0]);
+               if (!ima_lsm_isset(nentry->lsm[i].rules))
                        pr_warn("rule for LSM \'%s\' is undefined\n",
                                nentry->lsm[i].args_p);
        }
@@ -590,7 +608,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
                int rc = 0;
                u32 osid;
 
-               if (!rule->lsm[i].rule) {
+               if (!ima_lsm_isset(rule->lsm[i].rules)) {
                        if (!rule->lsm[i].args_p)
                                continue;
                        else
@@ -603,14 +621,14 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
                        security_inode_getsecid(inode, &osid);
                        rc = ima_filter_rule_match(osid, rule->lsm[i].type,
                                                   Audit_equal,
-                                                  rule->lsm[i].rule);
+                                                  rule->lsm[i].rules);
                        break;
                case LSM_SUBJ_USER:
                case LSM_SUBJ_ROLE:
                case LSM_SUBJ_TYPE:
                        rc = ima_filter_rule_match(secid, rule->lsm[i].type,
                                                   Audit_equal,
-                                                  rule->lsm[i].rule);
+                                                  rule->lsm[i].rules);
                        break;
                default:
                        break;
@@ -1046,7 +1064,7 @@ static int ima_lsm_rule_init(struct ima_rule_entry *entry,
 {
        int result;
 
-       if (entry->lsm[lsm_rule].rule)
+       if (ima_lsm_isset(entry->lsm[lsm_rule].rules))
                return -EINVAL;
 
        entry->lsm[lsm_rule].args_p = match_strdup(args);
@@ -1056,8 +1074,8 @@ static int ima_lsm_rule_init(struct ima_rule_entry *entry,
        entry->lsm[lsm_rule].type = audit_type;
        result = ima_filter_rule_init(entry->lsm[lsm_rule].type, Audit_equal,
                                      entry->lsm[lsm_rule].args_p,
-                                     &entry->lsm[lsm_rule].rule);
-       if (!entry->lsm[lsm_rule].rule) {
+                                     &entry->lsm[lsm_rule].rules[0]);
+       if (!ima_lsm_isset(entry->lsm[lsm_rule].rules)) {
                pr_warn("rule for LSM \'%s\' is undefined\n",
                        entry->lsm[lsm_rule].args_p);
 
@@ -1954,7 +1972,7 @@ int ima_policy_show(struct seq_file *m, void *v)
        }
 
        for (i = 0; i < MAX_LSM_RULES; i++) {
-               if (entry->lsm[i].rule) {
+               if (ima_lsm_isset(entry->lsm[i].rules)) {
                        switch (i) {
                        case LSM_OBJ_USER:
                                seq_printf(m, pt(Opt_obj_user),