--- v14
+++ v24
@@ -1,207 +1,90 @@
-Change the secid parameter of security_audit_rule_match
-to a lsmblob structure pointer. Pass the entry from the
-lsmblob structure for the approprite slot to the LSM hook.
+Provide interfaces to map LSM slot numbers and LSM names.
+Update the LSM registration code to save this information.
-Change the users of security_audit_rule_match to use the
-lsmblob instead of a u32. In some cases this requires a
-temporary conversion using lsmblob_init() that will go
-away when other interfaces get converted.
-
-Reviewed-by: Kees Cook <keescook@chromium.org>
-Reviewed-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
- include/linux/security.h | 7 ++++---
- kernel/auditfilter.c | 6 ++++--
- kernel/auditsc.c | 14 ++++++++++----
- security/integrity/ima/ima.h | 4 ++--
- security/integrity/ima/ima_policy.c | 7 +++++--
- security/security.c | 8 +++++---
- 6 files changed, 30 insertions(+), 16 deletions(-)
+ include/linux/security.h | 4 ++++
+ security/security.c | 45 ++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 49 insertions(+)
diff --git a/include/linux/security.h b/include/linux/security.h
-index 3422726268d2..1988b728eb3a 100644
+index 4a109092a8d7..a99a4307176f 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
-@@ -1837,7 +1837,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 lsmblob *blob, u32 field, u32 op,
-+ void **lsmrule);
- void security_audit_rule_free(void **lsmrule);
-
- #else
-@@ -1853,8 +1854,8 @@ static inline int security_audit_rule_known(struct audit_krule *krule)
- return 0;
+@@ -192,6 +192,10 @@ static inline bool lsmblob_equal(struct lsmblob *bloba, struct lsmblob *blobb)
+ return !memcmp(bloba, blobb, sizeof(*bloba));
}
--static inline int security_audit_rule_match(u32 secid, u32 field, u32 op,
-- void **lsmrule)
-+static inline int security_audit_rule_match(struct lsmblob *blob, u32 field,
-+ u32 op, void **lsmrule)
- {
- return 0;
- }
-diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
-index 3a44abf4fced..509eb21eff7f 100644
---- a/kernel/auditfilter.c
-+++ b/kernel/auditfilter.c
-@@ -1327,6 +1327,7 @@ int audit_filter(int msgtype, unsigned int listtype)
- struct audit_field *f = &e->rule.fields[i];
- pid_t pid;
- u32 sid;
-+ struct lsmblob blob;
-
- switch (f->type) {
- case AUDIT_PID:
-@@ -1357,8 +1358,9 @@ int audit_filter(int msgtype, unsigned int listtype)
- case AUDIT_SUBJ_CLR:
- if (f->lsm_isset) {
- security_task_getsecid(current, &sid);
-- result = security_audit_rule_match(sid,
-- f->type, f->op,
-+ lsmblob_init(&blob, sid);
-+ result = security_audit_rule_match(
-+ &blob, f->type, f->op,
- f->lsm_rules);
- }
- break;
-diff --git a/kernel/auditsc.c b/kernel/auditsc.c
-index 0c239c29a9d5..ef2f5e7eec7b 100644
---- a/kernel/auditsc.c
-+++ b/kernel/auditsc.c
-@@ -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 lsmblob blob;
- unsigned int sessionid;
-
- cred = rcu_dereference_check(tsk->cred, tsk == current || task_creation);
-@@ -643,7 +644,9 @@ 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,
-+ lsmblob_init(&blob, sid);
-+ result = security_audit_rule_match(&blob,
-+ f->type,
- f->op,
- f->lsm_rules);
- }
-@@ -658,15 +661,17 @@ static int audit_filter_rules(struct task_struct *tsk,
- if (f->lsm_isset) {
- /* Find files that match */
- if (name) {
-+ lsmblob_init(&blob, name->osid);
- result = security_audit_rule_match(
-- name->osid,
-+ &blob,
- f->type,
- f->op,
- f->lsm_rules);
- } else if (ctx) {
- list_for_each_entry(n, &ctx->names_list, list) {
-+ lsmblob_init(&blob, name->osid);
- if (security_audit_rule_match(
-- n->osid,
-+ &blob,
- f->type,
- f->op,
- f->lsm_rules)) {
-@@ -678,7 +683,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,
-+ lsmblob_init(&blob, ctx->ipc.osid);
-+ if (security_audit_rule_match(&blob,
- f->type, f->op,
- f->lsm_rules))
- ++result;
-diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
-index df4ca482fb53..d95b0ece7434 100644
---- a/security/integrity/ima/ima.h
-+++ b/security/integrity/ima/ima.h
-@@ -381,8 +381,8 @@ static inline int security_filter_rule_init(u32 field, u32 op, char *rulestr,
- return -EINVAL;
- }
-
--static inline int security_filter_rule_match(u32 secid, u32 field, u32 op,
-- void *lsmrule)
-+static inline int security_filter_rule_match(struct lsmblob *blob, u32 field,
-+ u32 op, void *lsmrule)
- {
- return -EINVAL;
- }
-diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
-index 808c2515fc6a..27257af4a8cd 100644
---- a/security/integrity/ima/ima_policy.c
-+++ b/security/integrity/ima/ima_policy.c
-@@ -426,6 +426,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 lsmblob blob;
-
- if (!ima_lsm_isset(rule->lsm[i].rules))
- continue;
-@@ -435,7 +436,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,
-+ lsmblob_init(&blob, osid);
-+ rc = security_filter_rule_match(&blob,
- rule->lsm[i].type,
- Audit_equal,
- rule->lsm[i].rules);
-@@ -443,7 +445,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,
-+ lsmblob_init(&blob, secid);
-+ rc = security_filter_rule_match(&blob,
- rule->lsm[i].type,
- Audit_equal,
- rule->lsm[i].rules);
++/* Map lsm names to blob slot numbers */
++extern int lsm_name_to_slot(char *name);
++extern const char *lsm_slot_to_name(int slot);
++
+ /* These functions are in security/commoncap.c */
+ extern int cap_capable(const struct cred *cred, struct user_namespace *ns,
+ int cap, unsigned int opts);
diff --git a/security/security.c b/security/security.c
-index 214404a78db1..3a2529f36269 100644
+index 39dce9eb3bcd..05ce02ae7c46 100644
--- a/security/security.c
+++ b/security/security.c
-@@ -439,7 +439,7 @@ static int lsm_append(const char *new, char **result)
- /*
+@@ -474,6 +474,50 @@ static int lsm_append(const char *new, char **result)
* Current index to use while initializing the lsmblob secid list.
*/
--static int lsm_slot __initdata;
-+static int lsm_slot __lsm_ro_after_init;
+ static int lsm_slot __lsm_ro_after_init;
++static struct lsm_id *lsm_slotlist[LSMBLOB_ENTRIES] __lsm_ro_after_init;
++
++/**
++ * lsm_name_to_slot - Report the slot number for a security module
++ * @name: name of the security module
++ *
++ * Look up the slot number for the named security module.
++ * Returns the slot number or LSMBLOB_INVALID if @name is not
++ * a registered security module name.
++ */
++int lsm_name_to_slot(char *name)
++{
++ int i;
++
++ for (i = 0; i < lsm_slot; i++)
++ if (strcmp(lsm_slotlist[i]->lsm, name) == 0)
++ return i;
++
++ return LSMBLOB_INVALID;
++}
++
++/**
++ * lsm_slot_to_name - Get the name of the security module in a slot
++ * @slot: index into the interface LSM slot list.
++ *
++ * Provide the name of the security module associated with
++ * a interface LSM slot.
++ *
++ * If @slot is LSMBLOB_INVALID return the value
++ * for slot 0 if it has been set, otherwise NULL.
++ *
++ * Returns a pointer to the name string or NULL.
++ */
++const char *lsm_slot_to_name(int slot)
++{
++ if (slot == LSMBLOB_INVALID)
++ slot = 0;
++ else if (slot >= LSMBLOB_ENTRIES || slot < 0)
++ return NULL;
++
++ if (lsm_slotlist[slot] == NULL)
++ return NULL;
++ return lsm_slotlist[slot]->lsm;
++}
/**
* security_add_hooks - Add a modules hooks to the hook lists.
-@@ -2435,7 +2435,8 @@ void security_audit_rule_free(void **lsmrule)
- }
- }
-
--int security_audit_rule_match(u32 secid, u32 field, u32 op, void **lsmrule)
-+int security_audit_rule_match(struct lsmblob *blob, u32 field, u32 op,
-+ void **lsmrule)
- {
- struct security_hook_list *hp;
- int rc;
-@@ -2443,7 +2444,8 @@ int security_audit_rule_match(u32 secid, u32 field, u32 op, void **lsmrule)
- hlist_for_each_entry(hp, &security_hook_heads.audit_rule_match, list) {
- if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot))
- continue;
-- rc = hp->hook.audit_rule_match(secid, field, op,
-+ rc = hp->hook.audit_rule_match(blob->secid[hp->lsmid->slot],
-+ field, op,
- &lsmrule[hp->lsmid->slot]);
- if (rc)
- return rc;
+@@ -493,6 +537,7 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count,
+ if (lsmid->slot == LSMBLOB_NEEDED) {
+ if (lsm_slot >= LSMBLOB_ENTRIES)
+ panic("%s Too many LSMs registered.\n", __func__);
++ lsm_slotlist[lsm_slot] = lsmid;
+ lsmid->slot = lsm_slot++;
+ init_debug("%s assigned lsmblob slot %d\n", lsmid->lsm,
+ lsmid->slot);
--
-2.24.1
+2.25.4