--- v21
+++ v24
@@ -1,209 +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. The scaffolding function lsmblob_init()
-fills the blob 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 blob structure later in the series.
-At the point the use of lsmblob_init() is dropped.
-
-Reviewed-by: Kees Cook <keescook@chromium.org>
-Reviewed-by: John Johansen <john.johansen@canonical.com>
-Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
-Acked-by: Paul Moore <paul@paul-moore.com>
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 | 10 ++++++++--
- 6 files changed, 33 insertions(+), 15 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 c91389d7aebc..cbf1eea42e72 100644
+index 4a109092a8d7..a99a4307176f 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
-@@ -1879,7 +1879,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
-@@ -1895,8 +1896,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 45da229f9f1f..e27424216159 100644
---- a/kernel/auditfilter.c
-+++ b/kernel/auditfilter.c
-@@ -1331,6 +1331,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:
-@@ -1361,8 +1362,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 16e3430f7d07..7dd6b815a9eb 100644
---- a/kernel/auditsc.c
-+++ b/kernel/auditsc.c
-@@ -474,6 +474,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);
-@@ -672,7 +673,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);
- }
-@@ -687,15 +690,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)) {
-@@ -707,7 +712,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 38043074ce5e..d7fe1d5ee8c9 100644
---- a/security/integrity/ima/ima.h
-+++ b/security/integrity/ima/ima.h
-@@ -429,8 +429,8 @@ static inline void ima_filter_rule_free(void *lsmrule)
- {
- }
-
--static inline int ima_filter_rule_match(u32 secid, u32 field, u32 op,
-- void *lsmrule)
-+static inline int ima_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 50aa77139498..6b43ac22220c 100644
---- a/security/integrity/ima/ima_policy.c
-+++ b/security/integrity/ima/ima_policy.c
-@@ -500,6 +500,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 lsmdata;
-
- if (!ima_lsm_isset(rule->lsm[i].rules)) {
- if (!rule->lsm[i].args_p)
-@@ -512,14 +513,16 @@ 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 = ima_filter_rule_match(osid, rule->lsm[i].type,
-+ lsmblob_init(&lsmdata, osid);
-+ rc = ima_filter_rule_match(&lsmdata, rule->lsm[i].type,
- Audit_equal,
- rule->lsm[i].rules);
- break;
- case LSM_SUBJ_USER:
- case LSM_SUBJ_ROLE:
- case LSM_SUBJ_TYPE:
-- rc = ima_filter_rule_match(secid, rule->lsm[i].type,
-+ lsmblob_init(&lsmdata, secid);
-+ rc = ima_filter_rule_match(&lsmdata, rule->lsm[i].type,
- Audit_equal,
- rule->lsm[i].rules);
- default:
++/* 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 17d701cd7f69..f9a249a93215 100644
+index 39dce9eb3bcd..05ce02ae7c46 100644
--- a/security/security.c
+++ b/security/security.c
-@@ -2542,11 +2542,14 @@ void security_audit_rule_free(void **lsmrule)
- hlist_for_each_entry(hp, &security_hook_heads.audit_rule_free, list) {
- if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot))
- continue;
-+ if (lsmrule[hp->lsmid->slot] == NULL)
-+ continue;
- hp->hook.audit_rule_free(lsmrule[hp->lsmid->slot]);
- }
- }
+@@ -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 __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;
++}
--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;
-@@ -2554,7 +2557,10 @@ 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,
-+ if (lsmrule[hp->lsmid->slot] == NULL)
-+ continue;
-+ rc = hp->hook.audit_rule_match(blob->secid[hp->lsmid->slot],
-+ field, op,
- &lsmrule[hp->lsmid->slot]);
- if (rc)
- return rc;
+ /**
+ * security_add_hooks - Add a modules hooks to the hook lists.
+@@ -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