]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
lsm: use lsm_prop in security_audit_rule_match
authorCasey Schaufler <casey@schaufler-ca.com>
Wed, 9 Oct 2024 17:32:10 +0000 (10:32 -0700)
committerPaul Moore <paul@paul-moore.com>
Fri, 11 Oct 2024 18:34:12 +0000 (14:34 -0400)
Change the secid parameter of security_audit_rule_match
to a lsm_prop structure pointer. Pass the entry from the
lsm_prop structure for the approprite slot to the LSM hook.

Change the users of security_audit_rule_match to use the
lsm_prop instead of a u32. The scaffolding function lsmprop_init()
fills the structure with the value of the old secid, ensuring that
it is available to the appropriate module hook. The sources of
the secid, security_task_getsecid() and security_inode_getsecid(),
will be converted to use the lsm_prop structure later in the series.
At that point the use of lsmprop_init() is dropped.

Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
[PM: subject line tweak]
Signed-off-by: Paul Moore <paul@paul-moore.com>
12 files changed:
include/linux/lsm_hook_defs.h
include/linux/security.h
kernel/auditfilter.c
kernel/auditsc.c
security/apparmor/audit.c
security/apparmor/include/audit.h
security/integrity/ima/ima.h
security/integrity/ima/ima_policy.c
security/security.c
security/selinux/include/audit.h
security/selinux/ss/services.c
security/smack/smack_lsm.c

index 9eca013aa5e1f654050d8981d71543943c347a47..ea7f17e3775610815ba58606a34edf8438e073fc 100644 (file)
@@ -416,7 +416,8 @@ LSM_HOOK(void, LSM_RET_VOID, key_post_create_or_update, struct key *keyring,
 LSM_HOOK(int, 0, audit_rule_init, u32 field, u32 op, char *rulestr,
         void **lsmrule, gfp_t gfp)
 LSM_HOOK(int, 0, audit_rule_known, struct audit_krule *krule)
-LSM_HOOK(int, 0, audit_rule_match, u32 secid, u32 field, u32 op, void *lsmrule)
+LSM_HOOK(int, 0, audit_rule_match, struct lsm_prop *prop, u32 field, u32 op,
+        void *lsmrule)
 LSM_HOOK(void, LSM_RET_VOID, audit_rule_free, void *lsmrule)
 #endif /* CONFIG_AUDIT */
 
index 555249a8d1218942d044935b2ccde980693643f0..a4f020491e7cdea8bfcda7261707e3d0eee0e583 100644 (file)
@@ -2115,7 +2115,8 @@ static inline void security_key_post_create_or_update(struct key *keyring,
 int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule,
                             gfp_t gfp);
 int security_audit_rule_known(struct audit_krule *krule);
-int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule);
+int security_audit_rule_match(struct lsm_prop *prop, u32 field, u32 op,
+                             void *lsmrule);
 void security_audit_rule_free(void *lsmrule);
 
 #else
@@ -2131,8 +2132,8 @@ static inline int security_audit_rule_known(struct audit_krule *krule)
        return 0;
 }
 
-static inline int security_audit_rule_match(u32 secid, u32 field, u32 op,
-                                           void *lsmrule)
+static inline int security_audit_rule_match(struct lsm_prop *prop, u32 field,
+                                           u32 op, void *lsmrule)
 {
        return 0;
 }
index 470041c49a4497c2fab2f4b77943795b206b3cae..288a2092fd0dbf26ce798a1f5d40dabeebd823fe 100644 (file)
@@ -1339,8 +1339,8 @@ int audit_filter(int msgtype, unsigned int listtype)
 
                for (i = 0; i < e->rule.field_count; i++) {
                        struct audit_field *f = &e->rule.fields[i];
+                       struct lsm_prop prop = { };
                        pid_t pid;
-                       u32 sid;
 
                        switch (f->type) {
                        case AUDIT_PID:
@@ -1370,9 +1370,12 @@ int audit_filter(int msgtype, unsigned int listtype)
                        case AUDIT_SUBJ_SEN:
                        case AUDIT_SUBJ_CLR:
                                if (f->lsm_rule) {
-                                       security_current_getsecid_subj(&sid);
-                                       result = security_audit_rule_match(sid,
-                                                  f->type, f->op, f->lsm_rule);
+                                       /* scaffolding */
+                                       security_current_getsecid_subj(
+                                                       &prop.scaffold.secid);
+                                       result = security_audit_rule_match(
+                                                  &prop, f->type, f->op,
+                                                  f->lsm_rule);
                                }
                                break;
                        case AUDIT_EXE:
index cd57053b4a6993deaaad2f97407af2db87ade00a..aaf672a962d6a1ca289fd24605f4faca82ccb395 100644 (file)
@@ -471,6 +471,7 @@ static int audit_filter_rules(struct task_struct *tsk,
        const struct cred *cred;
        int i, need_sid = 1;
        u32 sid;
+       struct lsm_prop prop = { };
        unsigned int sessionid;
 
        if (ctx && rule->prio <= ctx->prio)
@@ -681,7 +682,10 @@ static int audit_filter_rules(struct task_struct *tsk,
                                        security_current_getsecid_subj(&sid);
                                        need_sid = 0;
                                }
-                               result = security_audit_rule_match(sid, f->type,
+                               /* scaffolding */
+                               prop.scaffold.secid = sid;
+                               result = security_audit_rule_match(&prop,
+                                                                  f->type,
                                                                   f->op,
                                                                   f->lsm_rule);
                        }
@@ -696,15 +700,19 @@ static int audit_filter_rules(struct task_struct *tsk,
                        if (f->lsm_rule) {
                                /* Find files that match */
                                if (name) {
+                                       /* scaffolding */
+                                       prop.scaffold.secid = name->osid;
                                        result = security_audit_rule_match(
-                                                               name->osid,
+                                                               &prop,
                                                                f->type,
                                                                f->op,
                                                                f->lsm_rule);
                                } else if (ctx) {
                                        list_for_each_entry(n, &ctx->names_list, list) {
+                                               /* scaffolding */
+                                               prop.scaffold.secid = n->osid;
                                                if (security_audit_rule_match(
-                                                               n->osid,
+                                                               &prop,
                                                                f->type,
                                                                f->op,
                                                                f->lsm_rule)) {
@@ -716,7 +724,9 @@ static int audit_filter_rules(struct task_struct *tsk,
                                /* Find ipc objects that match */
                                if (!ctx || ctx->type != AUDIT_IPC)
                                        break;
-                               if (security_audit_rule_match(ctx->ipc.osid,
+                               /* scaffolding */
+                               prop.scaffold.secid = ctx->ipc.osid;
+                               if (security_audit_rule_match(&prop,
                                                              f->type, f->op,
                                                              f->lsm_rule))
                                        ++result;
index 6b5181c668b5b7c1937e16ef703fbfe10e1fcb5f..87df6fa2a48d771fb755419732d04c53e4a32077 100644 (file)
@@ -264,13 +264,17 @@ int aa_audit_rule_known(struct audit_krule *rule)
        return 0;
 }
 
-int aa_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule)
+int aa_audit_rule_match(struct lsm_prop *prop, u32 field, u32 op, void *vrule)
 {
        struct aa_audit_rule *rule = vrule;
        struct aa_label *label;
        int found = 0;
 
-       label = aa_secid_to_label(sid);
+       /* scaffolding */
+       if (!prop->apparmor.label && prop->scaffold.secid)
+               label = aa_secid_to_label(prop->scaffold.secid);
+       else
+               label = prop->apparmor.label;
 
        if (!label)
                return -ENOENT;
index 0c8cc86b417b563f644d6d06e7e7c250750372fb..e27229349abbe1f293f1133254325c622cce9069 100644 (file)
@@ -202,6 +202,6 @@ static inline int complain_error(int error)
 void aa_audit_rule_free(void *vrule);
 int aa_audit_rule_init(u32 field, u32 op, char *rulestr, void **vrule, gfp_t gfp);
 int aa_audit_rule_known(struct audit_krule *rule);
-int aa_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule);
+int aa_audit_rule_match(struct lsm_prop *prop, u32 field, u32 op, void *vrule);
 
 #endif /* __AA_AUDIT_H */
index 3c323ca213d42cfd782a0c350590e4a2d5dc23d5..cdfe8c8c7bac980e9cec9c4472120e2487d5e867 100644 (file)
@@ -555,7 +555,7 @@ static inline void ima_filter_rule_free(void *lsmrule)
 {
 }
 
-static inline int ima_filter_rule_match(u32 secid, u32 field, u32 op,
+static inline int ima_filter_rule_match(struct lsm_prop *prop, u32 field, u32 op,
                                        void *lsmrule)
 {
        return -EINVAL;
index 09da8e63923956855897795df8cb3748e39b2fd3..22a62e675ebc58e309b64831773f85412fa36131 100644 (file)
@@ -635,7 +635,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
                return false;
        for (i = 0; i < MAX_LSM_RULES; i++) {
                int rc = 0;
-               u32 osid;
+               struct lsm_prop prop = { };
 
                if (!lsm_rule->lsm[i].rule) {
                        if (!lsm_rule->lsm[i].args_p)
@@ -649,15 +649,18 @@ retry:
                case LSM_OBJ_USER:
                case LSM_OBJ_ROLE:
                case LSM_OBJ_TYPE:
-                       security_inode_getsecid(inode, &osid);
-                       rc = ima_filter_rule_match(osid, lsm_rule->lsm[i].type,
+                       /* scaffolding */
+                       security_inode_getsecid(inode, &prop.scaffold.secid);
+                       rc = ima_filter_rule_match(&prop, lsm_rule->lsm[i].type,
                                                   Audit_equal,
                                                   lsm_rule->lsm[i].rule);
                        break;
                case LSM_SUBJ_USER:
                case LSM_SUBJ_ROLE:
                case LSM_SUBJ_TYPE:
-                       rc = ima_filter_rule_match(secid, lsm_rule->lsm[i].type,
+                       /* scaffolding */
+                       prop.scaffold.secid = secid;
+                       rc = ima_filter_rule_match(&prop, lsm_rule->lsm[i].type,
                                                   Audit_equal,
                                                   lsm_rule->lsm[i].rule);
                        break;
index 6875eb4a59fcc140a9aee1c9abef5e3859171351..deab7f912e12d4f545702c3530d69bd25d16ec72 100644 (file)
@@ -5570,7 +5570,7 @@ void security_audit_rule_free(void *lsmrule)
 
 /**
  * security_audit_rule_match() - Check if a label matches an audit rule
- * @secid: security label
+ * @prop: security label
  * @field: LSM audit field
  * @op: matching operator
  * @lsmrule: audit rule
@@ -5581,9 +5581,10 @@ void security_audit_rule_free(void *lsmrule)
  * Return: Returns 1 if secid matches the rule, 0 if it does not, -ERRNO on
  *         failure.
  */
-int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule)
+int security_audit_rule_match(struct lsm_prop *prop, u32 field, u32 op,
+                             void *lsmrule)
 {
-       return call_int_hook(audit_rule_match, secid, field, op, lsmrule);
+       return call_int_hook(audit_rule_match, prop, field, op, lsmrule);
 }
 #endif /* CONFIG_AUDIT */
 
index 168d17be7df3b983d059cde9e9760e69fa07ea3f..c745ea2a993d3549bf013593dee11954a07db120 100644 (file)
@@ -41,7 +41,7 @@ void selinux_audit_rule_free(void *rule);
 
 /**
  * selinux_audit_rule_match - determine if a context ID matches a rule.
- * @sid: the context ID to check
+ * @prop: includes the context ID to check
  * @field: the field this rule refers to
  * @op: the operator the rule uses
  * @rule: pointer to the audit rule to check against
@@ -49,7 +49,7 @@ void selinux_audit_rule_free(void *rule);
  * Returns 1 if the context id matches the rule, 0 if it does not, and
  * -errno on failure.
  */
-int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *rule);
+int selinux_audit_rule_match(struct lsm_prop *prop, u32 field, u32 op, void *rule);
 
 /**
  * selinux_audit_rule_known - check to see if rule contains selinux fields.
index a9830fbfc5c66c62c6d93643f142de25c347c5a7..e0c14773a7b755c059f16a9ffd18da40ae36a933 100644 (file)
@@ -3635,7 +3635,7 @@ int selinux_audit_rule_known(struct audit_krule *rule)
        return 0;
 }
 
-int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule)
+int selinux_audit_rule_match(struct lsm_prop *prop, u32 field, u32 op, void *vrule)
 {
        struct selinux_state *state = &selinux_state;
        struct selinux_policy *policy;
@@ -3661,10 +3661,14 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule)
                goto out;
        }
 
-       ctxt = sidtab_search(policy->sidtab, sid);
+       /* scaffolding */
+       if (!prop->selinux.secid && prop->scaffold.secid)
+               prop->selinux.secid = prop->scaffold.secid;
+
+       ctxt = sidtab_search(policy->sidtab, prop->selinux.secid);
        if (unlikely(!ctxt)) {
                WARN_ONCE(1, "selinux_audit_rule_match: unrecognized SID %d\n",
-                         sid);
+                         prop->selinux.secid);
                match = -ENOENT;
                goto out;
        }
index 370fd594da1252ec7f48d1bda5efdc28d1c32307..535233ad720361a9d39c428cfe4b87f3056be4e9 100644 (file)
@@ -4757,7 +4757,7 @@ static int smack_audit_rule_known(struct audit_krule *krule)
 
 /**
  * smack_audit_rule_match - Audit given object ?
- * @secid: security id for identifying the object to test
+ * @prop: security id for identifying the object to test
  * @field: audit rule flags given from user-space
  * @op: required testing operator
  * @vrule: smack internal rule presentation
@@ -4765,7 +4765,8 @@ static int smack_audit_rule_known(struct audit_krule *krule)
  * The core Audit hook. It's used to take the decision of
  * whether to audit or not to audit a given object.
  */
-static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule)
+static int smack_audit_rule_match(struct lsm_prop *prop, u32 field, u32 op,
+                                 void *vrule)
 {
        struct smack_known *skp;
        char *rule = vrule;
@@ -4778,7 +4779,11 @@ static int smack_audit_rule_match(u32 secid, u32 field, u32 op, void *vrule)
        if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
                return 0;
 
-       skp = smack_from_secid(secid);
+       /* scaffolding */
+       if (!prop->smack.skp && prop->scaffold.secid)
+               skp = smack_from_secid(prop->scaffold.secid);
+       else
+               skp = prop->smack.skp;
 
        /*
         * No need to do string comparisons. If a match occurs,