/* * Copyright (c) 2017, Intel Corporation * * SPDX-License-Identifier: Apache 2.0 */ #ifndef _ZEPHYR_SYSCALL_HANDLER_H_ #define _ZEPHYR_SYSCALL_HANDLER_H_ #ifdef CONFIG_USERSPACE #ifndef _ASMLANGUAGE #include #include #include extern const _k_syscall_handler_t _k_syscall_table[K_SYSCALL_LIMIT]; /** * @brief Runtime expression check for system call arguments * * Used in handler functions to perform various runtime checks on arguments, * and generate a kernel oops if anything is not expected * * @param expr Boolean expression to verify, a false result will trigger an * oops * @param ssf Syscall stack frame argument passed to the handler function */ #define _SYSCALL_VERIFY(expr, ssf) \ do { \ if (!(expr)) { \ printk("FATAL: syscall failed check: " #expr "\n"); \ _arch_syscall_oops(ssf); \ } \ } while (0) /** * @brief Runtime check that a user thread has proper access to a memory area * * Checks that the particular memory area is readable or writable by the * currently running thread if the CPU was in user mode, and generates a kernel * oops if it wasn't. Prevents userspace from getting the kernel to read or * modify memory the thread does not have access to, or passing in garbage * pointers that would crash/pagefault the kernel if accessed. * * @param ptr Memory area to examine * @param size Size of the memory area * @param write If the thread should be able to write to this memory, not just * read it * @param ssf Syscall stack frame argument passed to the handler function */ #define _SYSCALL_MEMORY(ptr, size, write, ssf) \ _SYSCALL_VERIFY(!_arch_buffer_validate((void *)ptr, size, write), ssf) /** * @brief Runtime check that a pointer is a kernel object of expected type * * Passes along arguments to _k_object_validate() and triggers a kernel oops * if the object wasn't valid or had incorrect permissions. * * @param ptr Untrusted kernel object pointer * @param type Expected kernel object type * @param init Whether this is an init function handler * @param ssf Syscall stack frame argument passed to the handler function */ #define _SYSCALL_IS_OBJ(ptr, type, init, ssf) \ _SYSCALL_VERIFY(!_k_object_validate((void *)ptr, type, init), ssf) /* Convenience macros for handler implementations */ #define _SYSCALL_ARG0 ARG_UNUSED(arg1); ARG_UNUSED(arg2); ARG_UNUSED(arg3); \ ARG_UNUSED(arg4); ARG_UNUSED(arg5); ARG_UNUSED(arg6) #define _SYSCALL_ARG1 ARG_UNUSED(arg2); ARG_UNUSED(arg3); ARG_UNUSED(arg4); \ ARG_UNUSED(arg5); ARG_UNUSED(arg6) #define _SYSCALL_ARG2 ARG_UNUSED(arg3); ARG_UNUSED(arg4); ARG_UNUSED(arg5); \ ARG_UNUSED(arg6) #define _SYSCALL_ARG3 ARG_UNUSED(arg4); ARG_UNUSED(arg5); ARG_UNUSED(arg6) #define _SYSCALL_ARG4 ARG_UNUSED(arg5); ARG_UNUSED(arg6) #define _SYSCALL_ARG5 ARG_UNUSED(arg6) #endif /* _ASMLANGUAGE */ #endif /* CONFIG_USERSPACE */ #endif /* _ZEPHYR_SYSCALL_H_ */