From a89bf01192232c4e8c5536b99c10deeabd4d6a79 Mon Sep 17 00:00:00 2001 From: Andrew Boie Date: Mon, 9 Oct 2017 14:47:55 -0700 Subject: [PATCH] kernel: add k_object_access_revoke() system call Does the opposite of k_object_access_grant(); the provided thread will lose access to that kernel object. If invoked from userspace the caller must hace sufficient access to that object and permission on the thread being revoked access. Fix documentation for k_object_access_grant() API to reflect that permission on the thread parameter is needed as well. Signed-off-by: Andrew Boie --- include/kernel.h | 20 +++++++++++++++++++- kernel/include/syscall_handler.h | 8 ++++++++ kernel/userspace.c | 17 +++++++++++++++++ kernel/userspace_handler.c | 12 ++++++++++++ 4 files changed, 56 insertions(+), 1 deletion(-) diff --git a/include/kernel.h b/include/kernel.h index 7dd572367c9..4d4dbd7e7fe 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -204,6 +204,13 @@ static inline void _impl_k_object_access_grant(void *object, ARG_UNUSED(thread); } +static inline void _impl_k_object_access_revoke(void *object, + struct k_thread *thread) +{ + ARG_UNUSED(object); + ARG_UNUSED(thread); +} + static inline void _impl_k_object_access_all_grant(void *object) { ARG_UNUSED(object); @@ -215,13 +222,24 @@ static inline void _impl_k_object_access_all_grant(void *object) * * The thread will be granted access to the object if the caller is from * supervisor mode, or the caller is from user mode AND has permissions - * on the object already. + * on both the object and the thread whose access is being granted. * * @param object Address of kernel object * @param thread Thread to grant access to the object */ __syscall void k_object_access_grant(void *object, struct k_thread *thread); +/** + * grant a thread access to a kernel object + * + * The thread will lose access to the object if the caller is from + * supervisor mode, or the caller is from user mode AND has permissions + * on both the object and the thread whose access is being revoked. + * + * @param object Address of kernel object + * @param thread Thread to remove access to the object + */ +__syscall void k_object_access_revoke(void *object, struct k_thread *thread); /** * grant all present and future threads access to an object diff --git a/kernel/include/syscall_handler.h b/kernel/include/syscall_handler.h index 696b66e702b..b2fe6b4e214 100644 --- a/kernel/include/syscall_handler.h +++ b/kernel/include/syscall_handler.h @@ -90,6 +90,14 @@ extern void _thread_perms_inherit(struct k_thread *parent, */ extern void _thread_perms_set(struct _k_object *ko, struct k_thread *thread); +/** + * Revoke a thread's permission to a kernel object + * + * @param ko Kernel object metadata to update + * @param thread The thread to grant permission + */ +extern void _thread_perms_clear(struct _k_object *ko, struct k_thread *thread); + /** * Grant all current and future threads access to a kernel object * diff --git a/kernel/userspace.c b/kernel/userspace.c index 80e8d14b68d..8f97957dd16 100644 --- a/kernel/userspace.c +++ b/kernel/userspace.c @@ -130,6 +130,14 @@ void _thread_perms_set(struct _k_object *ko, struct k_thread *thread) } } +void _thread_perms_clear(struct _k_object *ko, struct k_thread *thread) +{ + if (thread->base.perm_index < 8 * CONFIG_MAX_THREAD_BYTES) { + sys_bitfield_clear_bit((mem_addr_t)&ko->perms, + thread->base.perm_index); + } +} + static int thread_perms_test(struct _k_object *ko) { if (_current->base.perm_index < 8 * CONFIG_MAX_THREAD_BYTES) { @@ -180,6 +188,15 @@ void _impl_k_object_access_grant(void *object, struct k_thread *thread) } } +void _impl_k_object_access_revoke(void *object, struct k_thread *thread) +{ + struct _k_object *ko = _k_object_find(object); + + if (ko) { + _thread_perms_clear(ko, thread); + } +} + void _impl_k_object_access_all_grant(void *object) { struct _k_object *ko = _k_object_find(object); diff --git a/kernel/userspace_handler.c b/kernel/userspace_handler.c index e0379d6b9cb..cc25e11823f 100644 --- a/kernel/userspace_handler.c +++ b/kernel/userspace_handler.c @@ -47,6 +47,18 @@ _SYSCALL_HANDLER2(k_object_access_grant, object, thread) return 0; } +_SYSCALL_HANDLER2(k_object_access_revoke, object, thread) +{ + struct _k_object *ko; + + _SYSCALL_OBJ(thread, K_OBJ_THREAD); + ko = validate_any_object((void *)object); + _SYSCALL_VERIFY_MSG(ko, "object %p access denied", (void *)object); + _thread_perms_clear(ko, (struct k_thread *)thread); + + return 0; +} + _SYSCALL_HANDLER1(k_object_access_all_grant, object) { struct _k_object *ko;