lsm: use lsm_prop in security_audit_rule_match

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>
This commit is contained in:
Casey Schaufler 2024-10-09 10:32:10 -07:00 committed by Paul Moore
parent ed870e35db
commit 870b7fdc66
12 changed files with 63 additions and 31 deletions

View 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, LSM_HOOK(int, 0, audit_rule_init, u32 field, u32 op, char *rulestr,
void **lsmrule, gfp_t gfp) void **lsmrule, gfp_t gfp)
LSM_HOOK(int, 0, audit_rule_known, struct audit_krule *krule) 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) LSM_HOOK(void, LSM_RET_VOID, audit_rule_free, void *lsmrule)
#endif /* CONFIG_AUDIT */ #endif /* CONFIG_AUDIT */

View 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, int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule,
gfp_t gfp); gfp_t gfp);
int security_audit_rule_known(struct audit_krule *krule); 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); void security_audit_rule_free(void *lsmrule);
#else #else
@ -2131,8 +2132,8 @@ static inline int security_audit_rule_known(struct audit_krule *krule)
return 0; return 0;
} }
static inline int security_audit_rule_match(u32 secid, u32 field, u32 op, static inline int security_audit_rule_match(struct lsm_prop *prop, u32 field,
void *lsmrule) u32 op, void *lsmrule)
{ {
return 0; return 0;
} }

View File

@ -1339,8 +1339,8 @@ int audit_filter(int msgtype, unsigned int listtype)
for (i = 0; i < e->rule.field_count; i++) { for (i = 0; i < e->rule.field_count; i++) {
struct audit_field *f = &e->rule.fields[i]; struct audit_field *f = &e->rule.fields[i];
struct lsm_prop prop = { };
pid_t pid; pid_t pid;
u32 sid;
switch (f->type) { switch (f->type) {
case AUDIT_PID: case AUDIT_PID:
@ -1370,9 +1370,12 @@ int audit_filter(int msgtype, unsigned int listtype)
case AUDIT_SUBJ_SEN: case AUDIT_SUBJ_SEN:
case AUDIT_SUBJ_CLR: case AUDIT_SUBJ_CLR:
if (f->lsm_rule) { if (f->lsm_rule) {
security_current_getsecid_subj(&sid); /* scaffolding */
result = security_audit_rule_match(sid, security_current_getsecid_subj(
f->type, f->op, f->lsm_rule); &prop.scaffold.secid);
result = security_audit_rule_match(
&prop, f->type, f->op,
f->lsm_rule);
} }
break; break;
case AUDIT_EXE: case AUDIT_EXE:

View File

@ -471,6 +471,7 @@ static int audit_filter_rules(struct task_struct *tsk,
const struct cred *cred; const struct cred *cred;
int i, need_sid = 1; int i, need_sid = 1;
u32 sid; u32 sid;
struct lsm_prop prop = { };
unsigned int sessionid; unsigned int sessionid;
if (ctx && rule->prio <= ctx->prio) if (ctx && rule->prio <= ctx->prio)
@ -681,7 +682,10 @@ static int audit_filter_rules(struct task_struct *tsk,
security_current_getsecid_subj(&sid); security_current_getsecid_subj(&sid);
need_sid = 0; 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->op,
f->lsm_rule); f->lsm_rule);
} }
@ -696,15 +700,19 @@ static int audit_filter_rules(struct task_struct *tsk,
if (f->lsm_rule) { if (f->lsm_rule) {
/* Find files that match */ /* Find files that match */
if (name) { if (name) {
/* scaffolding */
prop.scaffold.secid = name->osid;
result = security_audit_rule_match( result = security_audit_rule_match(
name->osid, &prop,
f->type, f->type,
f->op, f->op,
f->lsm_rule); f->lsm_rule);
} else if (ctx) { } else if (ctx) {
list_for_each_entry(n, &ctx->names_list, list) { list_for_each_entry(n, &ctx->names_list, list) {
/* scaffolding */
prop.scaffold.secid = n->osid;
if (security_audit_rule_match( if (security_audit_rule_match(
n->osid, &prop,
f->type, f->type,
f->op, f->op,
f->lsm_rule)) { f->lsm_rule)) {
@ -716,7 +724,9 @@ static int audit_filter_rules(struct task_struct *tsk,
/* Find ipc objects that match */ /* Find ipc objects that match */
if (!ctx || ctx->type != AUDIT_IPC) if (!ctx || ctx->type != AUDIT_IPC)
break; 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->type, f->op,
f->lsm_rule)) f->lsm_rule))
++result; ++result;

View File

@ -264,13 +264,17 @@ int aa_audit_rule_known(struct audit_krule *rule)
return 0; 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_audit_rule *rule = vrule;
struct aa_label *label; struct aa_label *label;
int found = 0; 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) if (!label)
return -ENOENT; return -ENOENT;

View File

@ -202,6 +202,6 @@ static inline int complain_error(int error)
void aa_audit_rule_free(void *vrule); 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_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_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 */ #endif /* __AA_AUDIT_H */

View 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) void *lsmrule)
{ {
return -EINVAL; return -EINVAL;

View File

@ -635,7 +635,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
return false; return false;
for (i = 0; i < MAX_LSM_RULES; i++) { for (i = 0; i < MAX_LSM_RULES; i++) {
int rc = 0; int rc = 0;
u32 osid; struct lsm_prop prop = { };
if (!lsm_rule->lsm[i].rule) { if (!lsm_rule->lsm[i].rule) {
if (!lsm_rule->lsm[i].args_p) if (!lsm_rule->lsm[i].args_p)
@ -649,15 +649,18 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
case LSM_OBJ_USER: case LSM_OBJ_USER:
case LSM_OBJ_ROLE: case LSM_OBJ_ROLE:
case LSM_OBJ_TYPE: case LSM_OBJ_TYPE:
security_inode_getsecid(inode, &osid); /* scaffolding */
rc = ima_filter_rule_match(osid, lsm_rule->lsm[i].type, security_inode_getsecid(inode, &prop.scaffold.secid);
rc = ima_filter_rule_match(&prop, lsm_rule->lsm[i].type,
Audit_equal, Audit_equal,
lsm_rule->lsm[i].rule); lsm_rule->lsm[i].rule);
break; break;
case LSM_SUBJ_USER: case LSM_SUBJ_USER:
case LSM_SUBJ_ROLE: case LSM_SUBJ_ROLE:
case LSM_SUBJ_TYPE: 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, Audit_equal,
lsm_rule->lsm[i].rule); lsm_rule->lsm[i].rule);
break; break;

View File

@ -5570,7 +5570,7 @@ void security_audit_rule_free(void *lsmrule)
/** /**
* security_audit_rule_match() - Check if a label matches an audit rule * security_audit_rule_match() - Check if a label matches an audit rule
* @secid: security label * @prop: security label
* @field: LSM audit field * @field: LSM audit field
* @op: matching operator * @op: matching operator
* @lsmrule: audit rule * @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 * Return: Returns 1 if secid matches the rule, 0 if it does not, -ERRNO on
* failure. * 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 */ #endif /* CONFIG_AUDIT */

View File

@ -41,7 +41,7 @@ void selinux_audit_rule_free(void *rule);
/** /**
* selinux_audit_rule_match - determine if a context ID matches a 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 * @field: the field this rule refers to
* @op: the operator the rule uses * @op: the operator the rule uses
* @rule: pointer to the audit rule to check against * @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 * Returns 1 if the context id matches the rule, 0 if it does not, and
* -errno on failure. * -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. * selinux_audit_rule_known - check to see if rule contains selinux fields.

View File

@ -3635,7 +3635,7 @@ int selinux_audit_rule_known(struct audit_krule *rule)
return 0; 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_state *state = &selinux_state;
struct selinux_policy *policy; struct selinux_policy *policy;
@ -3661,10 +3661,14 @@ int selinux_audit_rule_match(u32 sid, u32 field, u32 op, void *vrule)
goto out; 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)) { if (unlikely(!ctxt)) {
WARN_ONCE(1, "selinux_audit_rule_match: unrecognized SID %d\n", WARN_ONCE(1, "selinux_audit_rule_match: unrecognized SID %d\n",
sid); prop->selinux.secid);
match = -ENOENT; match = -ENOENT;
goto out; goto out;
} }

View File

@ -4757,7 +4757,7 @@ static int smack_audit_rule_known(struct audit_krule *krule)
/** /**
* smack_audit_rule_match - Audit given object ? * 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 * @field: audit rule flags given from user-space
* @op: required testing operator * @op: required testing operator
* @vrule: smack internal rule presentation * @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 * The core Audit hook. It's used to take the decision of
* whether to audit or not to audit a given object. * 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; struct smack_known *skp;
char *rule = vrule; 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) if (field != AUDIT_SUBJ_USER && field != AUDIT_OBJ_USER)
return 0; 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, * No need to do string comparisons. If a match occurs,