LCOV - code coverage report
Current view: top level - zephyr/internal - syscall_handler.h Hit Total Coverage
Test: new.info Lines: 31 35 88.6 %
Date: 2025-01-09 03:30:05

          Line data    Source code
       1           0 : /*
       2             :  * Copyright (c) 2017, Intel Corporation
       3             :  *
       4             :  * SPDX-License-Identifier: Apache-2.0
       5             :  */
       6             : #ifndef ZEPHYR_INCLUDE_SYSCALL_HANDLER_H_
       7             : #define ZEPHYR_INCLUDE_SYSCALL_HANDLER_H_
       8             : 
       9             : /**
      10             :  * @brief User mode and Syscall APIs
      11             :  * @defgroup syscall_apis User mode and Syscall APIs
      12             :  * @ingroup internal_api
      13             :  * @{
      14             :  */
      15             : 
      16             : #if defined(CONFIG_USERSPACE) || defined(__DOXYGEN__)
      17             : 
      18             : #ifndef _ASMLANGUAGE
      19             : #include <zephyr/kernel.h>
      20             : #include <zephyr/arch/arch_interface.h>
      21             : #include <zephyr/sys/math_extras.h>
      22             : #include <stdbool.h>
      23             : #include <zephyr/logging/log.h>
      24             : 
      25             : extern const _k_syscall_handler_t _k_syscall_table[K_SYSCALL_LIMIT];
      26             : 
      27             : enum _obj_init_check {
      28             :         _OBJ_INIT_TRUE = 0,
      29             :         _OBJ_INIT_FALSE = -1,
      30             :         _OBJ_INIT_ANY = 1
      31             : };
      32             : 
      33             : /**
      34             :  * Return true if we are currently handling a system call from user mode
      35             :  *
      36             :  * Inside z_vrfy functions, we always know that we are handling
      37             :  * a system call invoked from user context.
      38             :  *
      39             :  * However, some checks that are only relevant to user mode must
      40             :  * instead be placed deeper within the implementation. This
      41             :  * API is useful to conditionally make these checks.
      42             :  *
      43             :  * For performance reasons, whenever possible, checks should be placed
      44             :  * in the relevant z_vrfy function since these are completely skipped
      45             :  * when a syscall is invoked.
      46             :  *
      47             :  * This will return true only if we are handling a syscall for a
      48             :  * user thread. If the system call was invoked from supervisor mode,
      49             :  * or we are not handling a system call, this will return false.
      50             :  *
      51             :  * @note This is an internal API. Do not use unless you are extending
      52             :  *       functionality in the Zephyr tree.
      53             :  *
      54             :  * @return whether the current context is handling a syscall for a user
      55             :  *         mode thread
      56             :  */
      57           1 : static inline bool k_is_in_user_syscall(void)
      58             : {
      59             :         /* This gets set on entry to the syscall's generated z_mrsh
      60             :          * function and then cleared on exit. This code path is only
      61             :          * encountered when a syscall is made from user mode, system
      62             :          * calls from supervisor mode bypass everything directly to
      63             :          * the implementation function.
      64             :          */
      65             :         return !k_is_in_isr() && (arch_current_thread()->syscall_frame != NULL);
      66             : }
      67             : 
      68             : /**
      69             :  * Ensure a system object is a valid object of the expected type
      70             :  *
      71             :  * Searches for the object and ensures that it is indeed an object
      72             :  * of the expected type, that the caller has the right permissions on it,
      73             :  * and that the object has been initialized.
      74             :  *
      75             :  * This function is intended to be called on the kernel-side system
      76             :  * call handlers to validate kernel object pointers passed in from
      77             :  * userspace.
      78             :  *
      79             :  * @param ko Kernel object metadata pointer, or NULL
      80             :  * @param otype Expected type of the kernel object, or K_OBJ_ANY if type
      81             :  *        doesn't matter
      82             :  * @param init Indicate whether the object needs to already be in initialized
      83             :  *             or uninitialized state, or that we don't care
      84             :  * @note This is an internal API. Do not use unless you are extending
      85             :  *       functionality in the Zephyr tree.
      86             :  *
      87             :  * @return 0 If the object is valid
      88             :  *         -EBADF if not a valid object of the specified type
      89             :  *         -EPERM If the caller does not have permissions
      90             :  *         -EINVAL Object is not initialized
      91             :  */
      92           1 : int k_object_validate(struct k_object *ko, enum k_objects otype,
      93             :                       enum _obj_init_check init);
      94             : 
      95             : /**
      96             :  * Dump out error information on failed k_object_validate() call
      97             :  *
      98             :  * @param retval Return value from k_object_validate()
      99             :  * @param obj Kernel object we were trying to verify
     100             :  * @param ko If retval=-EPERM, struct k_object * that was looked up, or NULL
     101             :  * @param otype Expected type of the kernel object
     102             :  * @note This is an internal API. Do not use unless you are extending
     103             :  *       functionality in the Zephyr tree.
     104             :  *
     105             :  */
     106           1 : void k_object_dump_error(int retval, const void *obj,
     107             :                          struct k_object *ko, enum k_objects otype);
     108             : 
     109             : /**
     110             :  * Kernel object validation function
     111             :  *
     112             :  * Retrieve metadata for a kernel object. This function is implemented in
     113             :  * the gperf script footer, see gen_kobject_list.py
     114             :  *
     115             :  * @param obj Address of kernel object to get metadata
     116             :  * @return Kernel object's metadata, or NULL if the parameter wasn't the
     117             :  * memory address of a kernel object
     118             :  * @note This is an internal API. Do not use unless you are extending
     119             :  *       functionality in the Zephyr tree.
     120             :  *
     121             :  */
     122           1 : struct k_object *k_object_find(const void *obj);
     123             : 
     124             : typedef void (*_wordlist_cb_func_t)(struct k_object *ko, void *context);
     125             : 
     126             : /**
     127             :  * Iterate over all the kernel object metadata in the system
     128             :  *
     129             :  * @param func function to run on each struct k_object
     130             :  * @param context Context pointer to pass to each invocation
     131             :  * @note This is an internal API. Do not use unless you are extending
     132             :  *       functionality in the Zephyr tree.
     133             :  *
     134             :  */
     135           1 : void k_object_wordlist_foreach(_wordlist_cb_func_t func, void *context);
     136             : 
     137             : /**
     138             :  * Copy all kernel object permissions from the parent to the child
     139             :  *
     140             :  * @param parent Parent thread, to get permissions from
     141             :  * @param child Child thread, to copy permissions to
     142             :  * @note This is an internal API. Do not use unless you are extending
     143             :  *       functionality in the Zephyr tree.
     144             :  *
     145             :  */
     146           1 : void k_thread_perms_inherit(struct k_thread *parent, struct k_thread *child);
     147             : 
     148             : /**
     149             :  * Grant a thread permission to a kernel object
     150             :  *
     151             :  * @param ko Kernel object metadata to update
     152             :  * @param thread The thread to grant permission
     153             :  * @note This is an internal API. Do not use unless you are extending
     154             :  *       functionality in the Zephyr tree.
     155             :  *
     156             :  */
     157           1 : void k_thread_perms_set(struct k_object *ko, struct k_thread *thread);
     158             : 
     159             : /**
     160             :  * Revoke a thread's permission to a kernel object
     161             :  *
     162             :  * @param ko Kernel object metadata to update
     163             :  * @param thread The thread to grant permission
     164             :  * @note This is an internal API. Do not use unless you are extending
     165             :  *       functionality in the Zephyr tree.
     166             :  *
     167             :  */
     168           1 : void k_thread_perms_clear(struct k_object *ko, struct k_thread *thread);
     169             : 
     170             : /**
     171             :  * Revoke access to all objects for the provided thread
     172             :  *
     173             :  * @note Unlike k_thread_perms_clear(), this function will not clear
     174             :  * permissions on public objects.
     175             :  *
     176             :  * @note This is an internal API. Do not use unless you are extending
     177             :  *       functionality in the Zephyr tree.
     178             :  *
     179             :  * @param thread Thread object to revoke access
     180             :  */
     181           1 : void k_thread_perms_all_clear(struct k_thread *thread);
     182             : 
     183             : /**
     184             :  * Clear initialization state of a kernel object
     185             :  *
     186             :  * Intended for thread objects upon thread exit, or for other kernel objects
     187             :  * that were released back to an object pool.
     188             :  *
     189             :  * @param obj Address of the kernel object
     190             :  *
     191             :  * @note This is an internal API. Do not use unless you are extending
     192             :  *       functionality in the Zephyr tree.
     193             :  */
     194           1 : void k_object_uninit(const void *obj);
     195             : 
     196             : /**
     197             :  * Initialize and reset permissions to only access by the caller
     198             :  *
     199             :  * Intended for scenarios where objects are fetched from slab pools
     200             :  * and may have had different permissions set during prior usage.
     201             :  *
     202             :  * This is only intended for pools of objects, where such objects are
     203             :  * acquired and released to the pool. If an object has already been used,
     204             :  * we do not want stale permission information hanging around, the object
     205             :  * should only have permissions on the caller. Objects which are not
     206             :  * managed by a pool-like mechanism should not use this API.
     207             :  *
     208             :  * The object will be marked as initialized and the calling thread
     209             :  * granted access to it.
     210             :  *
     211             :  * @param obj Address of the kernel object
     212             :  * @note This is an internal API. Do not use unless you are extending
     213             :  *       functionality in the Zephyr tree.
     214             :  */
     215           1 : void k_object_recycle(const void *obj);
     216             : 
     217             : /**
     218             :  * @brief Obtain the size of a C string passed from user mode
     219             :  *
     220             :  * Given a C string pointer and a maximum size, obtain the true
     221             :  * size of the string (not including the trailing NULL byte) just as
     222             :  * if calling strnlen() on it, with the same semantics of strnlen() with
     223             :  * respect to the return value and the maxlen parameter.
     224             :  *
     225             :  * Any memory protection faults triggered by the examination of the string
     226             :  * will be safely handled and an error code returned.
     227             :  *
     228             :  * NOTE: Doesn't guarantee that user mode has actual access to this
     229             :  * string, you will need to still do a K_SYSCALL_MEMORY_READ()
     230             :  * with the obtained size value to guarantee this.
     231             :  *
     232             :  * @param src String to measure size of
     233             :  * @param maxlen Maximum number of characters to examine
     234             :  * @param err Pointer to int, filled in with -1 on memory error, 0 on
     235             :  *      success
     236             :  * @return undefined on error, or strlen(src) if that is less than maxlen, or
     237             :  *      maxlen if there were no NULL terminating characters within the
     238             :  *      first maxlen bytes.
     239             :  * @note This is an internal API. Do not use unless you are extending
     240             :  *       functionality in the Zephyr tree.
     241             :  */
     242           1 : static inline size_t k_usermode_string_nlen(const char *src, size_t maxlen,
     243             :                                         int *err)
     244             : {
     245             :         return arch_user_string_nlen(src, maxlen, err);
     246             : }
     247             : 
     248             : /**
     249             :  * @brief Copy data from userspace into a resource pool allocation
     250             :  *
     251             :  * Given a pointer and a size, allocate a similarly sized buffer in the
     252             :  * caller's resource pool and copy all the data within it to the newly
     253             :  * allocated buffer. This will need to be freed later with k_free().
     254             :  *
     255             :  * Checks are done to ensure that the current thread would have read
     256             :  * access to the provided buffer.
     257             :  *
     258             :  * @param src Source memory address
     259             :  * @param size Size of the memory buffer
     260             :  * @return An allocated buffer with the data copied within it, or NULL
     261             :  *      if some error condition occurred
     262             :  * @note This is an internal API. Do not use unless you are extending
     263             :  *       functionality in the Zephyr tree.
     264             :  */
     265           1 : void *k_usermode_alloc_from_copy(const void *src, size_t size);
     266             : 
     267             : /**
     268             :  * @brief Copy data from user mode
     269             :  *
     270             :  * Given a userspace pointer and a size, copies data from it into a provided
     271             :  * destination buffer, performing checks to ensure that the caller would have
     272             :  * appropriate access when in user mode.
     273             :  *
     274             :  * @param dst Destination memory buffer
     275             :  * @param src Source memory buffer, in userspace
     276             :  * @param size Number of bytes to copy
     277             :  * @retval 0 On success
     278             :  * @retval EFAULT On memory access error
     279             :  * @note This is an internal API. Do not use unless you are extending
     280             :  *       functionality in the Zephyr tree.
     281             :  */
     282           1 : int k_usermode_from_copy(void *dst, const void *src, size_t size);
     283             : 
     284             : /**
     285             :  * @brief Copy data to user mode
     286             :  *
     287             :  * Given a userspace pointer and a size, copies data to it from a provided
     288             :  * source buffer, performing checks to ensure that the caller would have
     289             :  * appropriate access when in user mode.
     290             :  *
     291             :  * @param dst Destination memory buffer, in userspace
     292             :  * @param src Source memory buffer
     293             :  * @param size Number of bytes to copy
     294             :  * @retval 0 On success
     295             :  * @retval EFAULT On memory access error
     296             :  * @note This is an internal API. Do not use unless you are extending
     297             :  *       functionality in the Zephyr tree.
     298             :  */
     299           1 : int k_usermode_to_copy(void *dst, const void *src, size_t size);
     300             : 
     301             : /**
     302             :  * @brief Copy a C string from userspace into a resource pool allocation
     303             :  *
     304             :  * Given a C string and maximum length, duplicate the string using an
     305             :  * allocation from the calling thread's resource pool. This will need to be
     306             :  * freed later with k_free().
     307             :  *
     308             :  * Checks are performed to ensure that the string is valid memory and that
     309             :  * the caller has access to it in user mode.
     310             :  *
     311             :  * @param src Source string pointer, in userspace
     312             :  * @param maxlen Maximum size of the string including trailing NULL
     313             :  * @return The duplicated string, or NULL if an error occurred.
     314             :  * @note This is an internal API. Do not use unless you are extending
     315             :  *       functionality in the Zephyr tree.
     316             :  */
     317           1 : char *k_usermode_string_alloc_copy(const char *src, size_t maxlen);
     318             : 
     319             : /**
     320             :  * @brief Copy a C string from userspace into a provided buffer
     321             :  *
     322             :  * Given a C string and maximum length, copy the string into a buffer.
     323             :  *
     324             :  * Checks are performed to ensure that the string is valid memory and that
     325             :  * the caller has access to it in user mode.
     326             :  *
     327             :  * @param dst Destination buffer
     328             :  * @param src Source string pointer, in userspace
     329             :  * @param maxlen Maximum size of the string including trailing NULL
     330             :  * @retval 0 on success
     331             :  * @retval EINVAL if the source string is too long with respect
     332             :  *      to maxlen
     333             :  * @retval EFAULT On memory access error
     334             :  * @note This is an internal API. Do not use unless you are extending
     335             :  *       functionality in the Zephyr tree.
     336             :  */
     337           1 : int k_usermode_string_copy(char *dst, const char *src, size_t maxlen);
     338             : 
     339             : /**
     340             :  * @brief Induce a kernel oops
     341             :  *
     342             :  * This macro can be used to induce a kernel oops which will kill the
     343             :  * calling thread.
     344             :  *
     345             :  * @param expr Expression to be evaluated
     346             :  *
     347             :  * @note This is an internal API. Do not use unless you are extending
     348             :  *       functionality in the Zephyr tree.
     349             :  */
     350           1 : #define K_OOPS(expr) \
     351             :         do { \
     352             :                 if (expr) { \
     353             :                         arch_syscall_oops(arch_current_thread()->syscall_frame); \
     354             :                 } \
     355             :         } while (false)
     356             : 
     357             : /**
     358             :  * @brief Runtime expression check for system call arguments
     359             :  *
     360             :  * Used in handler functions to perform various runtime checks on arguments,
     361             :  * and generate a kernel oops if anything is not expected, printing a custom
     362             :  * message.
     363             :  *
     364             :  * @param expr Boolean expression to verify, a false result will trigger an
     365             :  *             oops
     366             :  * @param fmt Printf-style format string (followed by appropriate variadic
     367             :  *            arguments) to print on verification failure
     368             :  * @return False on success, True on failure
     369             :  * @note This is an internal API. Do not use unless you are extending
     370             :  *       functionality in the Zephyr tree.
     371             :  */
     372           1 : #define K_SYSCALL_VERIFY_MSG(expr, fmt, ...) ({ \
     373             :         bool expr_copy = !(expr); \
     374             :         if (expr_copy) { \
     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__); \
     380             :         } \
     381             :         expr_copy; })
     382             : 
     383             : /**
     384             :  * @brief Runtime expression check for system call arguments
     385             :  *
     386             :  * Used in handler functions to perform various runtime checks on arguments,
     387             :  * and generate a kernel oops if anything is not expected.
     388             :  *
     389             :  * @param expr Boolean expression to verify, a false result will trigger an
     390             :  *             oops. A stringified version of this expression will be printed.
     391             :  * @return 0 on success, nonzero on failure
     392             :  * @note This is an internal API. Do not use unless you are extending
     393             :  *       functionality in the Zephyr tree.
     394             :  */
     395           1 : #define K_SYSCALL_VERIFY(expr) K_SYSCALL_VERIFY_MSG(expr, #expr)
     396             : 
     397             : /**
     398             :  * @brief Macro to check if size is negative
     399             :  *
     400             :  * K_SYSCALL_MEMORY can be called with signed/unsigned types
     401             :  * and because of that if we check if size is greater or equal to
     402             :  * zero, many static analyzers complain about no effect expression.
     403             :  *
     404             :  * @param ptr Memory area to examine
     405             :  * @param size Size of the memory area
     406             :  * @return true if size is valid, false otherwise
     407             :  * @note This is an internal API. Do not use unless you are extending
     408             :  *       functionality in the Zephyr tree.
     409             :  */
     410           1 : #define K_SYSCALL_MEMORY_SIZE_CHECK(ptr, size) \
     411             :         (((uintptr_t)(ptr) + (size)) >= (uintptr_t)(ptr))
     412             : 
     413             : /**
     414             :  * @brief Runtime check that a user thread has read and/or write permission to
     415             :  *        a memory area
     416             :  *
     417             :  * Checks that the particular memory area is readable and/or writeable by the
     418             :  * currently running thread if the CPU was in user mode, and generates a kernel
     419             :  * oops if it wasn't. Prevents userspace from getting the kernel to read and/or
     420             :  * modify memory the thread does not have access to, or passing in garbage
     421             :  * pointers that would crash/pagefault the kernel if dereferenced.
     422             :  *
     423             :  * @param ptr Memory area to examine
     424             :  * @param size Size of the memory area
     425             :  * @param write If the thread should be able to write to this memory, not just
     426             :  *              read it
     427             :  * @return 0 on success, nonzero on failure
     428             :  * @note This is an internal API. Do not use unless you are extending
     429             :  *       functionality in the Zephyr tree.
     430             :  */
     431           1 : #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)) \
     435             :                              == 0), \
     436             :                              "Memory region %p (size %zu) %s access denied", \
     437             :                              (void *)(ptr), (size_t)(size), \
     438             :                              (write) ? "write" : "read")
     439             : 
     440             : /**
     441             :  * @brief Runtime check that a user thread has read permission to a memory area
     442             :  *
     443             :  * Checks that the particular memory area is readable by the currently running
     444             :  * thread if the CPU was in user mode, and generates a kernel oops if it
     445             :  * wasn't. Prevents userspace from getting the kernel to read memory the thread
     446             :  * does not have access to, or passing in garbage pointers that would
     447             :  * crash/pagefault the kernel if dereferenced.
     448             :  *
     449             :  * @param ptr Memory area to examine
     450             :  * @param size Size of the memory area
     451             :  * @return 0 on success, nonzero on failure
     452             :  * @note This is an internal API. Do not use unless you are extending
     453             :  *       functionality in the Zephyr tree.
     454             :  */
     455           1 : #define K_SYSCALL_MEMORY_READ(ptr, size) \
     456             :         K_SYSCALL_MEMORY(ptr, size, 0)
     457             : 
     458             : /**
     459             :  * @brief Runtime check that a user thread has write permission to a memory area
     460             :  *
     461             :  * Checks that the particular memory area is readable and writable by the
     462             :  * currently running thread if the CPU was in user mode, and generates a kernel
     463             :  * oops if it wasn't. Prevents userspace from getting the kernel to read or
     464             :  * modify memory the thread does not have access to, or passing in garbage
     465             :  * pointers that would crash/pagefault the kernel if dereferenced.
     466             :  *
     467             :  * @param ptr Memory area to examine
     468             :  * @param size Size of the memory area
     469             :  * @return 0 on success, nonzero on failure
     470             :  *
     471             :  * @note This is an internal API. Do not use unless you are extending
     472             :  *       functionality in the Zephyr tree.
     473             :  */
     474           1 : #define K_SYSCALL_MEMORY_WRITE(ptr, size) \
     475             :         K_SYSCALL_MEMORY(ptr, size, 1)
     476             : 
     477           0 : #define K_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, write) \
     478             :         ({ \
     479             :                 size_t product; \
     480             :                 K_SYSCALL_VERIFY_MSG(!size_mul_overflow((size_t)(nmemb), \
     481             :                                                         (size_t)(size), \
     482             :                                                         &product), \
     483             :                                      "%zux%zu array is too large", \
     484             :                                      (size_t)(nmemb), (size_t)(size)) ||  \
     485             :                         K_SYSCALL_MEMORY(ptr, product, write); \
     486             :         })
     487             : 
     488             : /**
     489             :  * @brief Validate user thread has read permission for sized array
     490             :  *
     491             :  * Used when the memory region is expressed in terms of number of elements and
     492             :  * each element size, handles any overflow issues with computing the total
     493             :  * array bounds. Otherwise see _SYSCALL_MEMORY_READ.
     494             :  *
     495             :  * @param ptr Memory area to examine
     496             :  * @param nmemb Number of elements in the array
     497             :  * @param size Size of each array element
     498             :  * @return 0 on success, nonzero on failure
     499             :  * @note This is an internal API. Do not use unless you are extending
     500             :  *       functionality in the Zephyr tree.
     501             :  */
     502           1 : #define K_SYSCALL_MEMORY_ARRAY_READ(ptr, nmemb, size) \
     503             :         K_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, 0)
     504             : 
     505             : /**
     506             :  * @brief Validate user thread has read/write permission for sized array
     507             :  *
     508             :  * Used when the memory region is expressed in terms of number of elements and
     509             :  * each element size, handles any overflow issues with computing the total
     510             :  * array bounds. Otherwise see _SYSCALL_MEMORY_WRITE.
     511             :  *
     512             :  * @param ptr Memory area to examine
     513             :  * @param nmemb Number of elements in the array
     514             :  * @param size Size of each array element
     515             :  * @return 0 on success, nonzero on failure
     516             :  * @note This is an internal API. Do not use unless you are extending
     517             :  *       functionality in the Zephyr tree.
     518             :  */
     519           1 : #define K_SYSCALL_MEMORY_ARRAY_WRITE(ptr, nmemb, size) \
     520             :         K_SYSCALL_MEMORY_ARRAY(ptr, nmemb, size, 1)
     521             : 
     522           0 : static inline int k_object_validation_check(struct k_object *ko,
     523             :                                          const void *obj,
     524             :                                          enum k_objects otype,
     525             :                                          enum _obj_init_check init)
     526             : {
     527             :         int ret;
     528             : 
     529             :         ret = k_object_validate(ko, otype, init);
     530             : 
     531             : #ifdef CONFIG_LOG
     532             :         if (ret != 0) {
     533             :                 k_object_dump_error(ret, obj, ko, otype);
     534             :         }
     535             : #else
     536             :         ARG_UNUSED(obj);
     537             : #endif
     538             : 
     539             :         return ret;
     540             : }
     541             : 
     542           0 : #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")
     547             : 
     548             : /**
     549             :  * @brief Runtime check driver object pointer for presence of operation
     550             :  *
     551             :  * Validates if the driver object is capable of performing a certain operation.
     552             :  *
     553             :  * @param ptr Untrusted device instance object pointer
     554             :  * @param api_name Name of the driver API struct (e.g. gpio_driver_api)
     555             :  * @param op Driver operation (e.g. manage_callback)
     556             :  *
     557             :  * @return 0 on success, nonzero on failure
     558             :  *
     559             :  * @note This is an internal API. Do not use unless you are extending
     560             :  *       functionality in the Zephyr tree.
     561             :  */
     562           1 : #define K_SYSCALL_DRIVER_OP(ptr, api_name, op) \
     563             :         ({ \
     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 " \
     568             :                                     "instance %p", \
     569             :                                     # op, __device__); \
     570             :         })
     571             : 
     572             : /**
     573             :  * @brief Runtime check that device object is of a specific driver type
     574             :  *
     575             :  * Checks that the driver object passed in is initialized, the caller has
     576             :  * correct permissions, and that it belongs to the specified driver
     577             :  * subsystems. Additionally, all devices store a structure pointer of the
     578             :  * driver's API. If this doesn't match the value provided, the check will fail.
     579             :  *
     580             :  * This provides an easy way to determine if a device object not only
     581             :  * belongs to a particular subsystem, but is of a specific device driver
     582             :  * implementation. Useful for defining out-of-subsystem system calls
     583             :  * which are implemented for only one driver.
     584             :  *
     585             :  * @param _device Untrusted device pointer
     586             :  * @param _dtype Expected kernel object type for the provided device pointer
     587             :  * @param _api Expected driver API structure memory address
     588             :  * @return 0 on success, nonzero on failure
     589             :  * @note This is an internal API. Do not use unless you are extending
     590             :  *       functionality in the Zephyr tree.
     591             :  */
     592           1 : #define K_SYSCALL_SPECIFIC_DRIVER(_device, _dtype, _api) \
     593             :         ({ \
     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"); \
     598             :         })
     599             : 
     600             : /**
     601             :  * @brief Runtime check kernel object pointer for non-init functions
     602             :  *
     603             :  * Calls k_object_validate and triggers a kernel oops if the check fails.
     604             :  * For use in system call handlers which are not init functions; a fatal
     605             :  * error will occur if the object is not initialized.
     606             :  *
     607             :  * @param ptr Untrusted kernel object pointer
     608             :  * @param type Expected kernel object type
     609             :  * @return 0 on success, nonzero on failure
     610             :  * @note This is an internal API. Do not use unless you are extending
     611             :  *       functionality in the Zephyr tree.
     612             :  */
     613           1 : #define K_SYSCALL_OBJ(ptr, type) \
     614             :         K_SYSCALL_IS_OBJ(ptr, type, _OBJ_INIT_TRUE)
     615             : 
     616             : /**
     617             :  * @brief Runtime check kernel object pointer for non-init functions
     618             :  *
     619             :  * See description of _SYSCALL_IS_OBJ. No initialization checks are done.
     620             :  * Intended for init functions where objects may be re-initialized at will.
     621             :  *
     622             :  * @param ptr Untrusted kernel object pointer
     623             :  * @param type Expected kernel object type
     624             :  * @return 0 on success, nonzero on failure
     625             :  * @note This is an internal API. Do not use unless you are extending
     626             :  *       functionality in the Zephyr tree.
     627             :  */
     628             : 
     629           1 : #define K_SYSCALL_OBJ_INIT(ptr, type) \
     630             :         K_SYSCALL_IS_OBJ(ptr, type, _OBJ_INIT_ANY)
     631             : 
     632             : /**
     633             :  * @brief Runtime check kernel object pointer for non-init functions
     634             :  *
     635             :  * See description of _SYSCALL_IS_OBJ. Triggers a fatal error if the object is
     636             :  * initialized. Intended for init functions where objects, once initialized,
     637             :  * can only be re-used when their initialization state expires due to some
     638             :  * other mechanism.
     639             :  *
     640             :  * @param ptr Untrusted kernel object pointer
     641             :  * @param type Expected kernel object type
     642             :  * @return 0 on success, nonzero on failure
     643             :  * @note This is an internal API. Do not use unless you are extending
     644             :  *       functionality in the Zephyr tree.
     645             :  */
     646             : 
     647           1 : #define K_SYSCALL_OBJ_NEVER_INIT(ptr, type) \
     648             :         K_SYSCALL_IS_OBJ(ptr, type, _OBJ_INIT_FALSE)
     649             : 
     650             : #include <zephyr/driver-validation.h>
     651             : 
     652             : #endif /* _ASMLANGUAGE */
     653             : 
     654             : #endif /* CONFIG_USERSPACE */
     655             : /**
     656             :  * @}
     657             :  */
     658             : 
     659             : #endif /* ZEPHYR_INCLUDE_SYSCALL_HANDLER_H_ */

Generated by: LCOV version 1.14