1.. _kernelobjects: 2 3Kernel Objects 4############## 5 6A kernel object can be one of three classes of data: 7 8* A core kernel object, such as a semaphore, thread, pipe, etc. 9* A thread stack, which is an array of :c:struct:`z_thread_stack_element` 10 and declared with :c:macro:`K_THREAD_STACK_DEFINE()` 11* A device driver instance (const struct device) that belongs to one of a defined 12 set of subsystems 13 14The set of known kernel objects and driver subsystems is defined in 15include/kernel.h as :c:enum:`k_objects`. 16 17Kernel objects are completely opaque to user threads. User threads work 18with addresses to kernel objects when making API calls, but may never 19dereference these addresses, doing so will cause a memory protection fault. 20All kernel objects must be placed in memory that is not accessible by 21user threads. 22 23Since user threads may not directly manipulate kernel objects, all use of 24them must go through system calls. In order to perform a system call on 25a kernel object, checks are performed by system call handler functions 26that the kernel object address is valid and that the calling thread 27has sufficient permissions to work with it. 28 29Permission on an object also has the semantics of a reference to an object. 30This is significant for certain object APIs which do temporary allocations, 31or objects which themselves have been allocated from a runtime memory pool. 32 33If an object loses all references, two events may happen: 34 35* If the object has an associated cleanup function, the cleanup function 36 may be called to release any runtime-allocated buffers the object was using. 37 38* If the object itself was dynamically allocated, the memory for the object 39 will be freed. 40 41Object Placement 42**************** 43 44Kernel objects that are only used by supervisor threads have no restrictions 45and can be located anywhere in the binary, or even declared on stacks. However, 46to prevent accidental or intentional corruption by user threads, they must 47not be located in any memory that user threads have direct access to. 48 49In order for a static kernel object to be usable by a user thread via system 50call APIs, several conditions must be met on how the kernel object is declared: 51 52* The object must be declared as a top-level global at build time, such that it 53 appears in the ELF symbol table. It is permitted to declare kernel objects 54 with static scope. The post-build script :ref:`gen_kobject_list.py` scans the 55 generated ELF file to find kernel objects and places their memory addresses 56 in a special table of kernel object metadata. Kernel objects may be members 57 of arrays or embedded within other data structures. 58 59* Kernel objects must be located in memory reserved for the kernel. They 60 must not be located in any memory partitions that are user-accessible. 61 62* Any memory reserved for a kernel object must be used exclusively for that 63 object. Kernel objects may not be members of a union data type. 64 65Kernel objects that are found but do not meet the above conditions will not be 66included in the generated table that is used to validate kernel object pointers 67passed in from user mode. 68 69The debug output of the :ref:`gen_kobject_list.py` script may be useful when 70debugging why some object was unexpectedly not being tracked. This 71information will be printed if the script is run with the ``--verbose`` flag, 72or if the build system is invoked with verbose output. 73 74Dynamic Objects 75*************** 76 77Kernel objects may also be allocated at runtime if 78:kconfig:option:`CONFIG_DYNAMIC_OBJECTS` is enabled. In this case, the 79:c:func:`k_object_alloc` API may be used to instantiate an object from 80the calling thread's resource pool. Such allocations may be freed in two 81ways: 82 83* Supervisor threads may call :c:func:`k_object_free` to force a dynamic 84 object to be released. 85 86* If an object's references drop to zero (which happens when no threads have 87 permissions on it) the object will be automatically freed. User threads 88 may drop their own permission on an object with 89 :c:func:`k_object_release`, and their permissions are automatically 90 cleared when a thread terminates. Supervisor threads may additionally 91 revoke references for another thread using 92 :c:func:`k_object_access_revoke`. 93 94Because permissions are also used for reference counting, it is important for 95supervisor threads to acquire permissions on objects they are using even though 96the access control aspects of the permission system are not enforced. 97 98Implementation Details 99====================== 100 101The :ref:`gen_kobject_list.py` script is a post-build step which finds all the 102valid kernel object instances in the binary. It accomplishes this by parsing 103the DWARF debug information present in the generated ELF file for the kernel. 104 105Any instances of structs or arrays corresponding to kernel objects that meet 106the object placement criteria will have their memory addresses placed in a 107special perfect hash table of kernel objects generated by the 'gperf' tool. 108When a system call is made and the kernel is presented with a memory address 109of what may or may not be a valid kernel object, the address can be validated 110with a constant-time lookup in this table. 111 112Drivers are a special case. All drivers are instances of :c:struct:`device`, but 113it is important to know what subsystem a driver belongs to so that 114incorrect operations, such as calling a UART API on a sensor driver object, can 115be prevented. When a device struct is found, its API pointer is examined to 116determine what subsystem the driver belongs to. 117 118The table itself maps kernel object memory addresses to instances of 119:c:struct:`z_object`, which has all the metadata for that object. This 120includes: 121 122* A bitfield indicating permissions on that object. All threads have a 123 numerical ID assigned to them at build time, used to index the permission 124 bitfield for an object to see if that thread has permission on it. The size 125 of this bitfield is controlled by the :kconfig:option:`CONFIG_MAX_THREAD_BYTES` 126 option and the build system will generate an error if this value is too low. 127* A type field indicating what kind of object this is, which is some 128 instance of :c:enum:`k_objects`. 129* A set of flags for that object. This is currently used to track 130 initialization state and whether an object is public or not. 131* An extra data field. The semantics of this field vary by object type, see 132 the definition of :c:union:`z_object_data`. 133 134Dynamic objects allocated at runtime are tracked in a runtime red/black tree 135which is used in parallel to the gperf table when validating object pointers. 136 137Supervisor Thread Access Permission 138*********************************** 139 140Supervisor threads can access any kernel object. However, permissions for 141supervisor threads are still tracked for two reasons: 142 143* If a supervisor thread calls :c:func:`k_thread_user_mode_enter`, the 144 thread will then run in user mode with any permissions it had been granted 145 (in many cases, by itself) when it was a supervisor thread. 146 147* If a supervisor thread creates a user thread with the 148 :c:macro:`K_INHERIT_PERMS` option, the child thread will be granted the 149 same permissions as the parent thread, except the parent thread object. 150 151User Thread Access Permission 152***************************** 153 154By default, when a user thread is created, it will only have access permissions 155on its own thread object. Other kernel objects by default are not usable. 156Access to them needs to be explicitly or implicitly granted. There are several 157ways to do this. 158 159* If a thread is created with the :c:macro:`K_INHERIT_PERMS`, that thread 160 will inherit all the permissions of the parent thread, except the parent 161 thread object. 162 163* A thread that has permission on an object, or is running in supervisor mode, 164 may grant permission on that object to another thread via the 165 :c:func:`k_object_access_grant` API. The convenience pseudo-function 166 :c:func:`k_thread_access_grant` may also be used, which accepts an arbitrary 167 number of pointers to kernel objects and calls 168 :c:func:`k_object_access_grant` on each of them. The thread being granted 169 permission, or the object whose access is being granted, do not need to be 170 in an initialized state. If the caller is from user mode, the caller must 171 have permissions on both the kernel object and the target thread object. 172 173* Supervisor threads may declare a particular kernel object to be a public 174 object, usable by all current and future threads with the 175 :c:func:`k_object_access_all_grant` API. You must assume that any 176 untrusted or exploited code will then be able to access the object. Use 177 this API with caution! 178 179* If a thread was declared statically with :c:macro:`K_THREAD_DEFINE()`, 180 then the :c:macro:`K_THREAD_ACCESS_GRANT()` may be used to grant that thread 181 access to a set of kernel objects at boot time. 182 183Once a thread has been granted access to an object, such access may be 184removed with the :c:func:`k_object_access_revoke` API. This API is not 185available to user threads, however user threads may use 186:c:func:`k_object_release` to relinquish their own permissions on an 187object. 188 189API calls from supervisor mode to set permissions on kernel objects that are 190not being tracked by the kernel will be no-ops. Doing the same from user mode 191will result in a fatal error for the calling thread. 192 193Objects allocated with :c:func:`k_object_alloc` implicitly grant 194permission on the allocated object to the calling thread. 195 196Initialization State 197******************** 198 199Most operations on kernel objects will fail if the object is considered to be 200in an uninitialized state. The appropriate init function for the object must 201be performed first. 202 203Some objects will be implicitly initialized at boot: 204 205* Kernel objects that were declared with static initialization macros 206 (such as :c:macro:`K_SEM_DEFINE` for semaphores) will be in an initialized 207 state at build time. 208 209* Device driver objects are considered initialized after their init function 210 is run by the kernel early in the boot process. 211 212If a kernel object is initialized with a private static initializer, the object 213must have :c:func:`k_object_init` called on it at some point by a supervisor 214thread, otherwise the kernel will consider the object uninitialized if accessed 215by a user thread. This is very uncommon, typically only for kernel objects that 216are embedded within some larger struct and initialized statically. 217 218.. code-block:: c 219 220 struct foo { 221 struct k_sem sem; 222 ... 223 }; 224 225 struct foo my_foo = { 226 .sem = Z_SEM_INITIALIZER(my_foo.sem, 0, 1), 227 ... 228 }; 229 230 ... 231 k_object_init(&my_foo.sem); 232 ... 233 234 235Creating New Kernel Object Types 236******************************** 237 238When implementing new kernel features or driver subsystems, it may be necessary 239to define some new kernel object types. There are different steps needed 240for creating core kernel objects and new driver subsystems. 241 242Creating New Core Kernel Objects 243================================ 244 245* In ``scripts/build/gen_kobject_list.py``, add the name of the struct to the 246 :py:data:`kobjects` list. 247 248Instances of the new struct should now be tracked. 249 250Creating New Driver Subsystem Kernel Objects 251============================================ 252 253All driver instances are :c:struct:`device`. They are differentiated by 254what API struct they are set to. 255 256* In ``scripts/build/gen_kobject_list.py``, add the name of the API struct for the 257 new subsystem to the :py:data:`subsystems` list. 258 259Driver instances of the new subsystem should now be tracked. 260 261Configuration Options 262********************* 263 264Related configuration options: 265 266* :kconfig:option:`CONFIG_USERSPACE` 267* :kconfig:option:`CONFIG_MAX_THREAD_BYTES` 268 269API Reference 270************* 271 272.. doxygengroup:: usermode_apis 273