I like this design but there is an issue with Landlock though, see below.
On 13/05/2021 22:07, Casey Schaufler wrote:
When more than one security module is exporting data to
audit and networking sub-systems a single 32 bit integer
is no longer sufficient to represent the data. Add a
structure to be used instead.
The lsmblob structure is currently an array of
u32 "secids". There is an entry for each of the
security modules built into the system that would
use secids if active. The system assigns the module
a "slot" when it registers hooks. If modules are
compiled in but not registered there will be unused
slots.
A new lsm_id structure, which contains the name
of the LSM and its slot number, is created. There
is an instance for each LSM, which assigns the name
and passes it to the infrastructure to set the slot.
The audit rules data is expanded to use an array of
security module data rather than a single instance.
Because IMA uses the audit rule functions it is
affected as well.
Acked-by: Stephen Smalley <sds(a)tycho.nsa.gov>
Acked-by: Paul Moore <paul(a)paul-moore.com>
Acked-by: John Johansen <john.johansen(a)canonical.com>
Signed-off-by: Casey Schaufler <casey(a)schaufler-ca.com>
Cc: <bpf(a)vger.kernel.org>
Cc: linux-audit(a)redhat.com
Cc: linux-security-module(a)vger.kernel.org
Cc: selinux(a)vger.kernel.org
To: Mimi Zohar <zohar(a)linux.ibm.com>
To: Mickaël Salaün <mic(a)linux.microsoft.com>
---
include/linux/audit.h | 4 +-
include/linux/lsm_hooks.h | 12 ++++-
include/linux/security.h | 67 +++++++++++++++++++++++++--
kernel/auditfilter.c | 24 +++++-----
kernel/auditsc.c | 13 +++---
security/apparmor/lsm.c | 7 ++-
security/bpf/hooks.c | 12 ++++-
security/commoncap.c | 7 ++-
security/integrity/ima/ima_policy.c | 40 +++++++++++-----
security/landlock/cred.c | 2 +-
security/landlock/fs.c | 2 +-
security/landlock/ptrace.c | 2 +-
security/landlock/setup.c | 4 ++
security/landlock/setup.h | 1 +
security/loadpin/loadpin.c | 8 +++-
security/lockdown/lockdown.c | 7 ++-
security/safesetid/lsm.c | 8 +++-
security/security.c | 72 ++++++++++++++++++++++++-----
security/selinux/hooks.c | 8 +++-
security/smack/smack_lsm.c | 7 ++-
security/tomoyo/tomoyo.c | 8 +++-
security/yama/yama_lsm.c | 7 ++-
22 files changed, 262 insertions(+), 60 deletions(-)
[...]
diff --git a/security/landlock/setup.c b/security/landlock/setup.c
index f8e8e980454c..4a12666a4090 100644
--- a/security/landlock/setup.c
+++ b/security/landlock/setup.c
@@ -23,6 +23,10 @@ struct lsm_blob_sizes landlock_blob_sizes __lsm_ro_after_init = {
.lbs_superblock = sizeof(struct landlock_superblock_security),
};
+struct lsm_id landlock_lsmid __lsm_ro_after_init = {
+ .lsm = LANDLOCK_NAME,
It is missing: .slot = LSMBLOB_NEEDED,
You can run the Landlock tests please?
make -C tools/testing/selftests TARGETS=landlock gen_tar
tar -xf kselftest.tar.gz && ./run_kselftest.sh
+};
+
static int __init landlock_init(void)
{
landlock_add_cred_hooks();
[...]
diff --git a/security/security.c b/security/security.c
index e12a7c463468..a3276deb1b8a 100644
--- a/security/security.c
+++ b/security/security.c
@@ -344,6 +344,7 @@ static void __init ordered_lsm_init(void)
init_debug("sock blob size = %d\n", blob_sizes.lbs_sock);
init_debug("superblock blob size = %d\n", blob_sizes.lbs_superblock);
init_debug("task blob size = %d\n", blob_sizes.lbs_task);
+ init_debug("lsmblob size = %zu\n", sizeof(struct lsmblob));
/*
* Create any kmem_caches needed for blobs
@@ -471,21 +472,36 @@ static int lsm_append(const char *new, char **result)
return 0;
}
+/*
+ * Current index to use while initializing the lsmblob secid list.
+ */
+static int lsm_slot __lsm_ro_after_init;
+
/**
* security_add_hooks - Add a modules hooks to the hook lists.
* @hooks: the hooks to add
* @count: the number of hooks to add
- * @lsm: the name of the security module
+ * @lsmid: the identification information for the security module
*
* Each LSM has to register its hooks with the infrastructure.
+ * If the LSM is using hooks that export secids allocate a slot
+ * for it in the lsmblob.
*/
void __init security_add_hooks(struct security_hook_list *hooks, int count,
- char *lsm)
+ struct lsm_id *lsmid)
{
int i;
Could you add a WARN_ON(!lsmid->slot || !lsmid->name) here?
+ if (lsmid->slot == LSMBLOB_NEEDED) {
+ if (lsm_slot >= LSMBLOB_ENTRIES)
+ panic("%s Too many LSMs registered.\n", __func__);
+ lsmid->slot = lsm_slot++;
+ init_debug("%s assigned lsmblob slot %d\n", lsmid->lsm,
+ lsmid->slot);
+ }
+
for (i = 0; i < count; i++) {
- hooks[i].lsm = lsm;
+ hooks[i].lsmid = lsmid;
hlist_add_tail_rcu(&hooks[i].list, hooks[i].head);
}