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