6#ifndef ZEPHYR_INCLUDE_SYSCALL_HANDLER_H_
7#define ZEPHYR_INCLUDE_SYSCALL_HANDLER_H_
16#if defined(CONFIG_USERSPACE) || defined(__DOXYGEN__)
25extern const _k_syscall_handler_t _k_syscall_table[K_SYSCALL_LIMIT];
65 return !
k_is_in_isr() && (_current->syscall_frame != NULL);
93 enum _obj_init_check init);
124typedef void (*_wordlist_cb_func_t)(
struct k_object *ko,
void *context);
350#define K_OOPS(expr) \
353 arch_syscall_oops(_current->syscall_frame); \
372#define K_SYSCALL_VERIFY_MSG(expr, fmt, ...) ({ \
373 bool expr_copy = !(expr); \
375 TOOLCHAIN_IGNORE_WSHADOW_BEGIN \
376 LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); \
377 TOOLCHAIN_IGNORE_WSHADOW_END \
378 LOG_ERR("syscall %s failed check: " fmt, \
379 __func__, ##__VA_ARGS__); \
395#define K_SYSCALL_VERIFY(expr) K_SYSCALL_VERIFY_MSG(expr, #expr)
410#define K_SYSCALL_MEMORY_SIZE_CHECK(ptr, size) \
411 (((uintptr_t)(ptr) + (size)) >= (uintptr_t)(ptr))
431#define K_SYSCALL_MEMORY(ptr, size, write) \
432 K_SYSCALL_VERIFY_MSG(K_SYSCALL_MEMORY_SIZE_CHECK(ptr, size) \
433 && !Z_DETECT_POINTER_OVERFLOW(ptr, size) \
434 && (arch_buffer_validate((void *)(ptr), (size), (write)) \
436 "Memory region %p (size %zu) %s access denied", \
437 (void *)(ptr), (size_t)(size), \
438 (write) ? "write" : "read")
455#define K_SYSCALL_MEMORY_READ(ptr, size) \
456 K_SYSCALL_MEMORY(ptr, size, 0)
474#define K_SYSCALL_MEMORY_WRITE(ptr, size) \
475 K_SYSCALL_MEMORY(ptr, size, 1)
477#define K_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, write) \
480 K_SYSCALL_VERIFY_MSG(!size_mul_overflow((size_t)(nmemb), \
483 "%zux%zu array is too large", \
484 (size_t)(nmemb), (size_t)(size)) || \
485 K_SYSCALL_MEMORY(ptr, product, write); \
502#define K_SYSCALL_MEMORY_ARRAY_READ(ptr, nmemb, size) \
503 K_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, 0)
519#define K_SYSCALL_MEMORY_ARRAY_WRITE(ptr, nmemb, size) \
520 K_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, 1)
525 enum _obj_init_check init)
542#define K_SYSCALL_IS_OBJ(ptr, type, init) \
543 K_SYSCALL_VERIFY_MSG(k_object_validation_check( \
544 k_object_find((const void *)(ptr)), \
545 (const void *)(ptr), \
546 (type), (init)) == 0, "access denied")
562#define K_SYSCALL_DRIVER_OP(ptr, api_name, op) \
564 struct api_name *__device__ = (struct api_name *) \
565 ((const struct device *)(ptr))->api; \
566 K_SYSCALL_VERIFY_MSG(__device__->op != NULL, \
567 "Operation %s not defined for driver " \
592#define K_SYSCALL_SPECIFIC_DRIVER(_device, _dtype, _api) \
594 const struct device *_dev = (const struct device *)_device; \
595 K_SYSCALL_OBJ(_dev, _dtype) || \
596 K_SYSCALL_VERIFY_MSG(_dev->api == _api, \
597 "API structure mismatch"); \
613#define K_SYSCALL_OBJ(ptr, type) \
614 K_SYSCALL_IS_OBJ(ptr, type, _OBJ_INIT_TRUE)
629#define K_SYSCALL_OBJ_INIT(ptr, type) \
630 K_SYSCALL_IS_OBJ(ptr, type, _OBJ_INIT_ANY)
647#define K_SYSCALL_OBJ_NEVER_INIT(ptr, type) \
648 K_SYSCALL_IS_OBJ(ptr, type, _OBJ_INIT_FALSE)
650#include <zephyr/driver-validation.h>
size_t arch_user_string_nlen(const char *s, size_t maxsize, int *err)
Safely take the length of a potentially bad string.
bool k_is_in_isr(void)
Determine if code is running at interrupt level.
struct k_object * k_object_find(const void *obj)
Kernel object validation function.
void k_thread_perms_clear(struct k_object *ko, struct k_thread *thread)
Revoke a thread's permission to a kernel object.
void k_thread_perms_set(struct k_object *ko, struct k_thread *thread)
Grant a thread permission to a kernel object.
void * k_usermode_alloc_from_copy(const void *src, size_t size)
Copy data from userspace into a resource pool allocation.
static size_t k_usermode_string_nlen(const char *src, size_t maxlen, int *err)
Obtain the size of a C string passed from user mode.
Definition syscall_handler.h:242
char * k_usermode_string_alloc_copy(const char *src, size_t maxlen)
Copy a C string from userspace into a resource pool allocation.
void k_object_wordlist_foreach(_wordlist_cb_func_t func, void *context)
Iterate over all the kernel object metadata in the system.
void k_thread_perms_inherit(struct k_thread *parent, struct k_thread *child)
Copy all kernel object permissions from the parent to the child.
int k_usermode_string_copy(char *dst, const char *src, size_t maxlen)
Copy a C string from userspace into a provided buffer.
int k_object_validate(struct k_object *ko, enum k_objects otype, enum _obj_init_check init)
Ensure a system object is a valid object of the expected type.
static bool k_is_in_user_syscall(void)
Return true if we are currently handling a system call from user mode.
Definition syscall_handler.h:57
int k_usermode_from_copy(void *dst, const void *src, size_t size)
Copy data from user mode.
void k_thread_perms_all_clear(struct k_thread *thread)
Revoke access to all objects for the provided thread.
static int k_object_validation_check(struct k_object *ko, const void *obj, enum k_objects otype, enum _obj_init_check init)
Definition syscall_handler.h:522
void k_object_dump_error(int retval, const void *obj, struct k_object *ko, enum k_objects otype)
Dump out error information on failed k_object_validate() call.
void k_object_recycle(const void *obj)
Initialize and reset permissions to only access by the caller.
void k_object_uninit(const void *obj)
Clear initialization state of a kernel object.
int k_usermode_to_copy(void *dst, const void *src, size_t size)
Copy data to user mode.
k_objects
Kernel Object Types.
Definition kobject.h:30
Table generated by gperf, these objects are retrieved via k_object_find().
Definition kobject_internal.h:61
Thread Structure.
Definition thread.h:259