@@ -93,6 +93,45 @@ static inline void lsm_export_init(struct lsm_export *l)
memset(l, 0, sizeof(*l));
}
+/**
+ * lsm_export_secid - pull the useful secid out of a lsm_export
+ * @data: the containing data structure
+ * @secid: where to put the one that matters.
+ *
+ * Shim that will disappear when all lsm_export conversions are done.
+ */
+static inline void lsm_export_secid(struct lsm_export *data, u32 *secid)
+{
+ switch (data->flags) {
+ case LSM_EXPORT_NONE:
+ *secid = 0;
+ break;
+ case LSM_EXPORT_SELINUX:
+ *secid = data->selinux;
+ break;
+ case LSM_EXPORT_SMACK:
+ *secid = data->smack;
+ break;
+ case LSM_EXPORT_APPARMOR:
+ *secid = data->apparmor;
+ break;
+ default:
+ pr_warn("%s flags=0x%u - not a valid set\n", __func__,
+ data->flags);
+ *secid = 0;
+ break;
+ }
+}
+
+static inline void lsm_export_to_all(struct lsm_export *data, u32 secid)
+{
+ data->selinux = secid;
+ data->smack = secid;
+ data->apparmor = secid;
+ data->flags = LSM_EXPORT_SELINUX | LSM_EXPORT_SMACK |
+ LSM_EXPORT_APPARMOR;
+}
+
/* These functions are in security/commoncap.c */
extern int cap_capable(const struct cred *cred, struct user_namespace *ns,
int cap, unsigned int opts);
@@ -1712,7 +1751,8 @@ static inline int security_key_getsecurity(struct key *key, char **_buffer)
#ifdef CONFIG_SECURITY
int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule);
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_export *l, u32 field, u32 op,
+ void *lsmrule);
void security_audit_rule_free(void *lsmrule);
#else
@@ -1728,8 +1768,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_export *l, u32 field,
+ u32 op, void *lsmrule)
{
return 0;
}
@@ -1324,6 +1324,7 @@ int audit_filter(int msgtype, unsigned int listtype)
struct audit_field *f = &e->rule.fields[i];
pid_t pid;
u32 sid;
+ struct lsm_export le;
switch (f->type) {
case AUDIT_PID:
@@ -1354,7 +1355,8 @@ int audit_filter(int msgtype, unsigned int listtype)
case AUDIT_SUBJ_CLR:
if (f->lsm_rule) {
security_task_getsecid(current, &sid);
- result = security_audit_rule_match(sid,
+ lsm_export_to_all(&le, sid);
+ result = security_audit_rule_match(&le,
f->type, f->op, f->lsm_rule);
}
break;
@@ -445,6 +445,7 @@ static int audit_filter_rules(struct task_struct *tsk,
const struct cred *cred;
int i, need_sid = 1;
u32 sid;
+ struct lsm_export le;
unsigned int sessionid;
cred = rcu_dereference_check(tsk->cred, tsk == current || task_creation);
@@ -630,7 +631,8 @@ static int audit_filter_rules(struct task_struct *tsk,
security_task_getsecid(tsk, &sid);
need_sid = 0;
}
- result = security_audit_rule_match(sid, f->type,
+ lsm_export_to_all(&le, sid);
+ result = security_audit_rule_match(&le, f->type,
f->op,
f->lsm_rule);
}
@@ -645,15 +647,17 @@ static int audit_filter_rules(struct task_struct *tsk,
if (f->lsm_rule) {
/* Find files that match */
if (name) {
+ lsm_export_to_all(&le, name->osid);
result = security_audit_rule_match(
- name->osid,
+ &le,
f->type,
f->op,
f->lsm_rule);
} else if (ctx) {
list_for_each_entry(n, &ctx->names_list, list) {
+ lsm_export_to_all(&le, n->osid);
if (security_audit_rule_match(
- n->osid,
+ &le,
f->type,
f->op,
f->lsm_rule)) {
@@ -665,7 +669,8 @@ 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,
+ lsm_export_to_all(&le, ctx->ipc.osid);
+ if (security_audit_rule_match(&le,
f->type, f->op,
f->lsm_rule))
++result;
@@ -327,6 +327,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode,
for (i = 0; i < MAX_LSM_RULES; i++) {
int rc = 0;
u32 osid;
+ struct lsm_export le;
int retried = 0;
if (!rule->lsm[i].rule)
@@ -337,7 +338,8 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode,
case LSM_OBJ_ROLE:
case LSM_OBJ_TYPE:
security_inode_getsecid(inode, &osid);
- rc = security_filter_rule_match(osid,
+ lsm_export_to_all(&le, osid);
+ rc = security_filter_rule_match(&le,
rule->lsm[i].type,
Audit_equal,
rule->lsm[i].rule);
@@ -345,7 +347,8 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode,
case LSM_SUBJ_USER:
case LSM_SUBJ_ROLE:
case LSM_SUBJ_TYPE:
- rc = security_filter_rule_match(secid,
+ lsm_export_to_all(&le, secid);
+ rc = security_filter_rule_match(&le,
rule->lsm[i].type,
Audit_equal,
rule->lsm[i].rule);
@@ -712,45 +712,6 @@ int lsm_superblock_alloc(struct super_block *sb)
RC; \
})
-/**
- * lsm_export_secid - pull the useful secid out of a lsm_export
- * @data: the containing data structure
- * @secid: where to put the one that matters.
- *
- * Shim that will disappear when all lsm_export conversions are done.
- */
-static inline void lsm_export_secid(struct lsm_export *data, u32 *secid)
-{
- switch (data->flags) {
- case LSM_EXPORT_NONE:
- *secid = 0;
- break;
- case LSM_EXPORT_SELINUX:
- *secid = data->selinux;
- break;
- case LSM_EXPORT_SMACK:
- *secid = data->smack;
- break;
- case LSM_EXPORT_APPARMOR:
- *secid = data->apparmor;
- break;
- default:
- pr_warn("%s flags=0x%u - not a valid set\n", __func__,
- data->flags);
- *secid = 0;
- break;
- }
-}
-
-static inline void lsm_export_to_all(struct lsm_export *data, u32 secid)
-{
- data->selinux = secid;
- data->smack = secid;
- data->apparmor = secid;
- data->flags = LSM_EXPORT_SELINUX | LSM_EXPORT_SMACK |
- LSM_EXPORT_APPARMOR;
-}
-
/* Security operations */
int security_binder_set_context_mgr(struct task_struct *mgr)
@@ -2482,14 +2443,11 @@ void security_audit_rule_free(void *lsmrule)
call_void_hook(audit_rule_free, lsmrule);
}
-int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule)
+int security_audit_rule_match(struct lsm_export *l, u32 field, u32 op,
+ void *lsmrule)
{
- int rc;
- struct lsm_export data = { .flags = LSM_EXPORT_NONE };
- rc = call_int_hook(audit_rule_match, 0, &data, field, op, lsmrule);
- lsm_export_secid(&data, &secid);
- return rc;
+ return call_int_hook(audit_rule_match, 0, l, field, op, lsmrule);
}
#endif /* CONFIG_AUDIT */
Convert security_audit_rule_match to use the lsm_export structure instead of a u32 secid. There is some scaffolding involved that will be removed when the related data is updated. Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> --- include/linux/security.h | 46 +++++++++++++++++++++++++-- kernel/auditfilter.c | 4 ++- kernel/auditsc.c | 13 +++++--- security/integrity/ima/ima_policy.c | 7 +++-- security/security.c | 48 ++--------------------------- 5 files changed, 63 insertions(+), 55 deletions(-)