kernel: userspace: add k_object_is_valid()
This adds a function k_object_is_valid() to check if a kernel object exists, of certain type, and has been initialized. This replaces the same (or very similar) code that has been copied from kernel into the network subsystem. Signed-off-by: Daniel Leung <daniel.leung@intel.com>
This commit is contained in:
parent
cc219c0132
commit
d47b1c05f3
|
@ -192,6 +192,19 @@ __syscall void k_object_release(const void *object);
|
|||
*/
|
||||
void k_object_access_all_grant(const void *object);
|
||||
|
||||
/**
|
||||
* Check if a kernel object is of certain type and is valid.
|
||||
*
|
||||
* This checks if the kernel object exists, of certain type,
|
||||
* and has been initialized.
|
||||
*
|
||||
* @param obj Address of the kernel object
|
||||
* @param otype Object type (use K_OBJ_ANY for ignoring type checking)
|
||||
* @return True if kernel object (@a obj) exists, of certain type, and
|
||||
* has been initialized. False otherwise.
|
||||
*/
|
||||
bool k_object_is_valid(const void *obj, enum k_objects otype);
|
||||
|
||||
#else
|
||||
/* LCOV_EXCL_START */
|
||||
#define K_THREAD_ACCESS_GRANT(thread, ...)
|
||||
|
@ -236,6 +249,15 @@ static inline void k_object_access_all_grant(const void *object)
|
|||
{
|
||||
ARG_UNUSED(object);
|
||||
}
|
||||
|
||||
static inline bool k_object_is_valid(const void *obj, enum k_objects otype)
|
||||
{
|
||||
ARG_UNUSED(obj);
|
||||
ARG_UNUSED(otype);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* LCOV_EXCL_STOP */
|
||||
#endif /* !CONFIG_USERSPACE */
|
||||
|
||||
|
|
|
@ -7,8 +7,11 @@
|
|||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/syscall_handler.h>
|
||||
#include <zephyr/kernel_structs.h>
|
||||
#include <zephyr/toolchain.h>
|
||||
|
||||
static struct z_object *validate_any_object(const void *obj)
|
||||
static struct z_object *validate_kernel_object(const void *obj,
|
||||
enum k_objects otype,
|
||||
enum _obj_init_check init)
|
||||
{
|
||||
struct z_object *ko;
|
||||
int ret;
|
||||
|
@ -18,10 +21,10 @@ static struct z_object *validate_any_object(const void *obj)
|
|||
/* This can be any kernel object and it doesn't have to be
|
||||
* initialized
|
||||
*/
|
||||
ret = z_object_validate(ko, K_OBJ_ANY, _OBJ_INIT_ANY);
|
||||
ret = z_object_validate(ko, otype, init);
|
||||
if (ret != 0) {
|
||||
#ifdef CONFIG_LOG
|
||||
z_dump_object_error(ret, obj, ko, K_OBJ_ANY);
|
||||
z_dump_object_error(ret, obj, ko, otype);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
@ -29,6 +32,20 @@ static struct z_object *validate_any_object(const void *obj)
|
|||
return ko;
|
||||
}
|
||||
|
||||
static ALWAYS_INLINE struct z_object *validate_any_object(const void *obj)
|
||||
{
|
||||
return validate_kernel_object(obj, K_OBJ_ANY, _OBJ_INIT_ANY);
|
||||
}
|
||||
|
||||
bool k_object_is_valid(const void *obj, enum k_objects otype)
|
||||
{
|
||||
struct z_object *ko;
|
||||
|
||||
ko = validate_kernel_object(obj, otype, _OBJ_INIT_TRUE);
|
||||
|
||||
return (ko != NULL);
|
||||
}
|
||||
|
||||
/* Normally these would be included in userspace.c, but the way
|
||||
* syscall_dispatch.c declares weak handlers results in build errors if these
|
||||
* are located in userspace.c. Just put in a separate file.
|
||||
|
|
|
@ -152,19 +152,13 @@ struct net_if *z_impl_net_if_get_by_index(int index)
|
|||
struct net_if *z_vrfy_net_if_get_by_index(int index)
|
||||
{
|
||||
struct net_if *iface;
|
||||
struct z_object *zo;
|
||||
int ret;
|
||||
|
||||
iface = net_if_get_by_index(index);
|
||||
if (!iface) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
zo = z_object_find(iface);
|
||||
|
||||
ret = z_object_validate(zo, K_OBJ_NET_IF, _OBJ_INIT_TRUE);
|
||||
if (ret != 0) {
|
||||
z_dump_object_error(ret, iface, zo, K_OBJ_NET_IF);
|
||||
if (!k_object_is_valid(iface, K_OBJ_NET_IF)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -78,14 +78,7 @@ static inline void *get_sock_vtable(int sock,
|
|||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
if (ctx != NULL && z_is_in_user_syscall()) {
|
||||
struct z_object *zo;
|
||||
int ret;
|
||||
|
||||
zo = z_object_find(ctx);
|
||||
ret = z_object_validate(zo, K_OBJ_NET_SOCKET, _OBJ_INIT_TRUE);
|
||||
|
||||
if (ret != 0) {
|
||||
z_dump_object_error(ret, ctx, zo, K_OBJ_NET_SOCKET);
|
||||
if (!k_object_is_valid(ctx, K_OBJ_NET_SOCKET)) {
|
||||
/* Invalidate the context, the caller doesn't have
|
||||
* sufficient permission or there was some other
|
||||
* problem with the net socket object
|
||||
|
|
|
@ -1034,18 +1034,11 @@ ZTEST(mem_protect_kobj, test_create_new_invalid_prio_thread_from_user)
|
|||
/* Function to init thread's stack objects */
|
||||
static void thread_stack_init_objects(void *p1, void *p2, void *p3)
|
||||
{
|
||||
int ret;
|
||||
struct z_object *ko;
|
||||
|
||||
/* check that thread is initialized when running */
|
||||
ko = z_object_find(&child_thread);
|
||||
ret = z_object_validate(ko, K_OBJ_ANY, _OBJ_INIT_TRUE);
|
||||
zassert_equal(ret, _OBJ_INIT_TRUE);
|
||||
zassert_true(k_object_is_valid(&child_thread, K_OBJ_ANY));
|
||||
|
||||
/* check that stack is initialized when running */
|
||||
ko = z_object_find(child_stack);
|
||||
ret = z_object_validate(ko, K_OBJ_ANY, _OBJ_INIT_TRUE);
|
||||
zassert_equal(ret, _OBJ_INIT_TRUE);
|
||||
zassert_true(k_object_is_valid(child_stack, K_OBJ_ANY));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue