LSM: Create lsm_list_modules system call
authorCasey Schaufler <casey@schaufler-ca.com>
Tue, 12 Sep 2023 20:56:50 +0000 (13:56 -0700)
committerPaul Moore <paul@paul-moore.com>
Mon, 13 Nov 2023 03:54:42 +0000 (22:54 -0500)
Create a system call to report the list of Linux Security Modules
that are active on the system. The list is provided as an array
of LSM ID numbers.

The calling application can use this list determine what LSM
specific actions it might take. That might include choosing an
output format, determining required privilege or bypassing
security module specific behavior.

Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Serge Hallyn <serge@hallyn.com>
Reviewed-by: John Johansen <john.johansen@canonical.com>
Reviewed-by: Mickaël Salaün <mic@digikod.net>
Signed-off-by: Paul Moore <paul@paul-moore.com>
Documentation/userspace-api/lsm.rst
include/linux/syscalls.h
kernel/sys_ni.c
security/lsm_syscalls.c

index f8499f3e2826bcb81a349234799034f5b5368a3c..a76da373841b26c2e39de7a58b50c9fed91e1be2 100644 (file)
@@ -63,6 +63,9 @@ Get the specified security attributes of the current process
 .. kernel-doc:: security/lsm_syscalls.c
     :identifiers: sys_lsm_get_self_attr
 
+.. kernel-doc:: security/lsm_syscalls.c
+    :identifiers: sys_lsm_list_modules
+
 Additional documentation
 ========================
 
index 4e1e56a24f1e7d3a76a701eabe1bfb003a993f9f..feec5719750bef7839a24489b6e9ab13545ff476 100644 (file)
@@ -954,6 +954,7 @@ asmlinkage long sys_lsm_get_self_attr(unsigned int attr, struct lsm_ctx *ctx,
                                      size_t *size, __u32 flags);
 asmlinkage long sys_lsm_set_self_attr(unsigned int attr, struct lsm_ctx *ctx,
                                      size_t size, __u32 flags);
+asmlinkage long sys_lsm_list_modules(u64 *ids, size_t *size, u32 flags);
 
 /*
  * Architecture-specific system calls
index 1f61b8452a6e7a83945312216f7b6202373dd8a7..9fa5989bf2cec81b46e26d5a8150f98ad49da704 100644 (file)
@@ -173,6 +173,7 @@ COND_SYSCALL(fadvise64_64);
 COND_SYSCALL_COMPAT(fadvise64_64);
 COND_SYSCALL(lsm_get_self_attr);
 COND_SYSCALL(lsm_set_self_attr);
+COND_SYSCALL(lsm_list_modules);
 
 /* CONFIG_MMU only */
 COND_SYSCALL(swapon);
index 226ae80d9683cf1560dc07e3f2d0ba59150181c6..329aaca5efc03eeaa13ea86a7f46aecf019f2f31 100644 (file)
@@ -55,3 +55,42 @@ SYSCALL_DEFINE4(lsm_get_self_attr, unsigned int, attr, struct lsm_ctx __user *,
 {
        return security_getselfattr(attr, ctx, size, flags);
 }
+
+/**
+ * sys_lsm_list_modules - Return a list of the active security modules
+ * @ids: the LSM module ids
+ * @size: pointer to size of @ids, updated on return
+ * @flags: reserved for future use, must be zero
+ *
+ * Returns a list of the active LSM ids. On success this function
+ * returns the number of @ids array elements. This value may be zero
+ * if there are no LSMs active. If @size is insufficient to contain
+ * the return data -E2BIG is returned and @size is set to the minimum
+ * required size. In all other cases a negative value indicating the
+ * error is returned.
+ */
+SYSCALL_DEFINE3(lsm_list_modules, u64 __user *, ids, size_t __user *, size,
+               u32, flags)
+{
+       size_t total_size = lsm_active_cnt * sizeof(*ids);
+       size_t usize;
+       int i;
+
+       if (flags)
+               return -EINVAL;
+
+       if (get_user(usize, size))
+               return -EFAULT;
+
+       if (put_user(total_size, size) != 0)
+               return -EFAULT;
+
+       if (usize < total_size)
+               return -E2BIG;
+
+       for (i = 0; i < lsm_active_cnt; i++)
+               if (put_user(lsm_idlist[i]->id, ids++))
+                       return -EFAULT;
+
+       return lsm_active_cnt;
+}