kernel: add k_object_access_all_grant() API

This is a helper API for objects that are intended to be globally
accessible.

Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2017-10-04 12:10:32 -07:00 committed by Anas Nashif
commit 3b5ae804ad
2 changed files with 51 additions and 5 deletions

View file

@ -229,6 +229,23 @@ void _k_object_init(void *obj);
*/
void k_object_access_grant(void *object, struct k_thread *thread);
/**
* grant all present and future threads access to an object
*
* If the caller is from supervisor mode, or the caller is from user mode and
* have sufficient permissions on the object, then that object will have
* permissions granted to it for *all* current and future threads running in
* the system, effectively becoming a public kernel object.
*
* Use of this API should be avoided on systems that are running untrusted code
* as it is possible for such code to derive the addresses of kernel objects
* and perform unwanted operations on them.
*
* @param object Address of kernel object
*/
void k_object_access_all_grant(void *object);
#else
static inline int _k_object_validate(void *obj, enum k_objects otype, int init)
{

View file

@ -131,7 +131,17 @@ static int test_thread_perms(struct _k_object *ko)
return 0;
}
void k_object_access_grant(void *object, struct k_thread *thread)
/**
* Kernek object permission modification check
*
* Check that the caller has sufficient perms to modify access permissions for
* a particular kernel object. oops() if a user thread is trying to something
* forbidden.
*
* @param object to be modified
* @return NULL if the caller is a kernel thread and the object was not found
*/
static struct _k_object *access_check(void *object)
{
struct _k_object *ko = _k_object_find(object);
@ -146,7 +156,7 @@ void k_object_access_grant(void *object, struct k_thread *thread)
* objects won't ever be usable from userspace, but
* we shouldn't explode.
*/
return;
return NULL;
}
}
@ -156,11 +166,30 @@ void k_object_access_grant(void *object, struct k_thread *thread)
if (_is_thread_user() && !test_thread_perms(ko)) {
printk("insufficient permissions in current thread %p\n",
_current);
printk("Cannot grant access to %s %p for thread %p\n",
otype_to_str(ko->type), object, thread);
printk("Cannot grant access to %s %p\n",
otype_to_str(ko->type), object);
k_oops();
}
set_thread_perms(ko, thread);
return ko;
}
void k_object_access_grant(void *object, struct k_thread *thread)
{
struct _k_object *ko = access_check(object);
if (ko) {
set_thread_perms(ko, thread);
}
}
void k_object_access_all_grant(void *object)
{
struct _k_object *ko = access_check(object);
if (ko) {
memset(ko->perms, 0xFF, CONFIG_MAX_THREAD_BYTES);
}
}
int _k_object_validate(void *obj, enum k_objects otype, int init)