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,
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 */

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,
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;
}

View 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:

View 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;

View 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;

View 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 */

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)
{
return -EINVAL;

View 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 @@ static bool ima_match_rules(struct ima_rule_entry *rule,
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;

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
* @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 */

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.
* @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.

View 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;
}

View 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,