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

            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() && (_current->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(_current->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_DISABLE_WARNING(TOOLCHAIN_WARNING_SHADOW) \
     376              :                 LOG_MODULE_DECLARE(os, CONFIG_KERNEL_LOG_LEVEL); \
     377              :                 TOOLCHAIN_ENABLE_WARNING(TOOLCHAIN_WARNING_SHADOW) \
     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 2.0-1