[v3,7/9] LSM: lsm_set_self_attr syscall for LSM self attributes
Commit Message
Create a system call lsm_set_self_attr() to set a security
module maintained attribute of the current process. Historically
these attributes have been exposed to user space via entries in
procfs under /proc/self/attr.
The attribute value is provided in a lsm_ctx structure. The structure
identifys the size of the attribute, and the attribute value. The format
of the attribute value is defined by the security module, but will always
be \0 terminated if it is a string. The ctx_len value must always be
strlen(ctx)+1 if the value is a string. The flags field is reserved for
future security module specific use and must be 0.
---------------------------
| __u32 id |
---------------------------
| __u64 flags |
---------------------------
| __kernel_size_t ctx_len |
---------------------------
| __u8 ctx[ctx_len] |
---------------------------
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
---
Documentation/userspace-api/lsm.rst | 3 +++
include/linux/syscalls.h | 2 ++
kernel/sys_ni.c | 1 +
security/lsm_syscalls.c | 41 +++++++++++++++++++++++++++++
4 files changed, 47 insertions(+)
@@ -57,6 +57,9 @@ Get the 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_set_self_attr
+
.. kernel-doc:: security/lsm_syscalls.c
:identifiers: sys_lsm_module_list
@@ -1060,6 +1060,8 @@ asmlinkage long sys_set_mempolicy_home_node(unsigned long start, unsigned long l
asmlinkage long sys_lsm_get_self_attr(struct lsm_ctx *ctx, size_t *size,
int flags);
asmlinkage long sys_lsm_module_list(u32 *ids, size_t *size, int flags);
+asmlinkage long sys_lsm_set_self_attr(struct lsm_ctx *ctx, size_t size,
+ int flags);
/*
* Architecture-specific system calls
@@ -265,6 +265,7 @@ COND_SYSCALL(mremap);
/* security/lsm_syscalls.c */
COND_SYSCALL(lsm_get_self_attr);
COND_SYSCALL(lsm_module_list);
+COND_SYSCALL(lsm_set_self_attr);
/* security/keys/keyctl.c */
COND_SYSCALL(add_key);
@@ -181,6 +181,47 @@ SYSCALL_DEFINE3(lsm_get_self_attr,
return rc;
}
+/**
+ * sys_lsm_set_self_attr - Set current task's security module attribute
+ * @ctx: the LSM contexts
+ * @size: size of @ctx
+ * @flags: which attribute to set
+ *
+ * Sets the calling task's LSM context. On success this function
+ * returns 0. If the attribute specified cannot be set a negative
+ * value indicating the reason for the error is returned.
+ */
+SYSCALL_DEFINE3(lsm_set_self_attr,
+ struct lsm_ctx __user *, ctx,
+ __kernel_size_t, size,
+ __u32, flags)
+{
+ int rc = -EINVAL;
+ int attr;
+ void *page;
+ struct lsm_ctx *ip;
+
+ if (size > PAGE_SIZE)
+ return -E2BIG;
+ if (size <= sizeof(*ip))
+ return -EINVAL;
+
+ attr = attr_used_index(flags);
+ if (attr < 0)
+ return attr;
+
+ page = memdup_user(ctx, size);
+ if (IS_ERR(page))
+ return PTR_ERR(page);
+
+ ip = page;
+ if (sizeof(*ip) + ip->ctx_len <= size)
+ rc = security_setprocattr(ip->id, lsm_attr_names[attr].name,
+ ip->ctx, ip->ctx_len);
+ kfree(page);
+ return (rc > 0) ? 0 : rc;
+}
+
/**
* sys_lsm_module_list - Return a list of the active security modules
* @ids: the LSM module ids