kernel: add K_INHERIT_PERMS flag
By default, threads are created only having access to their own thread object and nothing else. This new flag to k_thread_create() gives the thread access to all objects that the parent had at the time it was created, with the exception of the parent thread itself. Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
7c1971edd5
commit
47f8fd1d4d
6 changed files with 75 additions and 2 deletions
|
@ -471,6 +471,12 @@ extern void k_call_stacks_analyze(void);
|
|||
*/
|
||||
#define K_USER (1 << 2)
|
||||
|
||||
/* Indicates that the thread being created should inherit all kernel object
|
||||
* permissions from the thread that created it. No effect if CONFIG_USERSPACE
|
||||
* is not enabled.
|
||||
*/
|
||||
#define K_INHERIT_PERMS (1 << 3)
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
/* x86 Bitmask definitions for threads user options */
|
||||
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
#if defined(CONFIG_DEBUG) || defined(CONFIG_STACK_CANARIES)
|
||||
#define KOBJECT_TEXT_AREA 256
|
||||
#else
|
||||
#define KOBJECT_TEXT_AREA 78
|
||||
#define KOBJECT_TEXT_AREA 118
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
/* We need to reserve room for the gperf generated hash functions.
|
||||
* Fortunately, unlike the data tables, the size of the code is
|
||||
* reasonably predictable; on x86 usually about 44 bytes with -Os.
|
||||
* reasonably predictable.
|
||||
*
|
||||
* The linker will error out complaining that the location pointer
|
||||
* is moving backwards if the reserved room isn't large enough.
|
||||
|
@ -19,6 +19,7 @@
|
|||
_kobject_text_area_end = .;
|
||||
#ifndef LINKER_PASS2
|
||||
PROVIDE(_k_object_find = .);
|
||||
PROVIDE(_k_object_wordlist_foreach = .);
|
||||
#endif
|
||||
. += KOBJECT_TEXT_AREA - (_kobject_text_area_end - _kobject_text_area_start);
|
||||
#endif /* CONFIG_USERSPACE */
|
||||
|
|
|
@ -63,6 +63,25 @@ extern void _dump_object_error(int retval, void *obj, struct _k_object *ko,
|
|||
*/
|
||||
extern struct _k_object *_k_object_find(void *obj);
|
||||
|
||||
typedef void (*_wordlist_cb_func_t)(struct _k_object *ko, void *context);
|
||||
|
||||
/**
|
||||
* Iterate over all the kernel object metadata in the system
|
||||
*
|
||||
* @param func function to run on each struct _k_object
|
||||
* @param context Context pointer to pass to each invocation
|
||||
*/
|
||||
extern void _k_object_wordlist_foreach(_wordlist_cb_func_t func, void *context);
|
||||
|
||||
/**
|
||||
* Copy all kernel object permissions from the parent to the child
|
||||
*
|
||||
* @param parent Parent thread, to get permissions from
|
||||
* @param child Child thread, to copy permissions to
|
||||
*/
|
||||
extern void _thread_perms_inherit(struct k_thread *parent,
|
||||
struct k_thread *child);
|
||||
|
||||
/**
|
||||
* Grant a thread permission to a kernel object
|
||||
*
|
||||
|
|
|
@ -286,6 +286,10 @@ void _setup_new_thread(struct k_thread *new_thread,
|
|||
|
||||
/* Any given thread has access to itself */
|
||||
k_object_access_grant(new_thread, new_thread);
|
||||
|
||||
if (options & K_INHERIT_PERMS) {
|
||||
_thread_perms_inherit(_current, new_thread);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -92,6 +92,36 @@ const char *otype_to_str(enum k_objects otype)
|
|||
#endif
|
||||
}
|
||||
|
||||
struct perm_ctx {
|
||||
int parent_id;
|
||||
int child_id;
|
||||
struct k_thread *parent;
|
||||
};
|
||||
|
||||
static void wordlist_cb(struct _k_object *ko, void *ctx_ptr)
|
||||
{
|
||||
struct perm_ctx *ctx = (struct perm_ctx *)ctx_ptr;
|
||||
|
||||
if (sys_bitfield_test_bit((mem_addr_t)&ko->perms, ctx->parent_id) &&
|
||||
(struct k_thread *)ko->name != ctx->parent) {
|
||||
sys_bitfield_set_bit((mem_addr_t)&ko->perms, ctx->child_id);
|
||||
}
|
||||
}
|
||||
|
||||
void _thread_perms_inherit(struct k_thread *parent, struct k_thread *child)
|
||||
{
|
||||
struct perm_ctx ctx = {
|
||||
parent->base.perm_index,
|
||||
child->base.perm_index,
|
||||
parent
|
||||
};
|
||||
|
||||
if ((ctx.parent_id < 8 * CONFIG_MAX_THREAD_BYTES) &&
|
||||
(ctx.child_id < 8 * CONFIG_MAX_THREAD_BYTES)) {
|
||||
_k_object_wordlist_foreach(wordlist_cb, &ctx);
|
||||
}
|
||||
}
|
||||
|
||||
void _thread_perms_set(struct _k_object *ko, struct k_thread *thread)
|
||||
{
|
||||
if (thread->base.perm_index < 8 * CONFIG_MAX_THREAD_BYTES) {
|
||||
|
|
|
@ -467,9 +467,11 @@ def find_kobjects(elf, syms):
|
|||
header = """%compare-lengths
|
||||
%define lookup-function-name _k_object_lookup
|
||||
%language=ANSI-C
|
||||
%global-table
|
||||
%struct-type
|
||||
%{
|
||||
#include <kernel.h>
|
||||
#include <syscall_handler.h>
|
||||
#include <string.h>
|
||||
%}
|
||||
struct _k_object;
|
||||
|
@ -485,6 +487,17 @@ struct _k_object *_k_object_find(void *obj)
|
|||
{
|
||||
return _k_object_lookup((const char *)obj, sizeof(void *));
|
||||
}
|
||||
|
||||
void _k_object_wordlist_foreach(_wordlist_cb_func_t func, void *context)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = MIN_HASH_VALUE; i <= MAX_HASH_VALUE; i++) {
|
||||
if (wordlist[i].name) {
|
||||
func(&wordlist[i], context);
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue