kernel: policy change for uninitailized objects

The old policy was that objects that are not marked as initialized may
be claimed by any thread, user or kernel.

This has some undesirable implications:
- Kernel objects that were initailized at build time via some
  _<object name>_INITIALIZER macro, not intended for userspace to ever
  use, could be 'stolen' if their memory addresses were figured out and
  _k_object_init() was never called on them.
- In general, a malicious thread could initialize all unclaimed objects
  it could find, resulting in denial of service for the threads that
  these objects were intended for.

Now, performing any operation in user mode on a kernel object,
initialized or not, required that the calling user thread have
permission on it. Such permission would have to be explicitly granted or
inherited from a supervisor thread, as with this change only supervisor
thread will be able to claim uninitialized objects in this way.

If an uninitialized kernel object has permissions granted to multiple
threads, whatever thread actually initializes the object will reset all
permission bits to zero and grant only the calling thread access to that
object.

In other words, granting access to an uninitialized object to several
threads means that "whichever of these threads (or any kernel thread)
who actually initializes this object will obtain exclusive access to
that object, which it then may grant to other threads as it sees fit."

Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2017-10-09 12:46:25 -07:00 committed by Andrew Boie
commit 3a0f6848e4

View file

@ -194,13 +194,10 @@ int _k_object_validate(void *obj, enum k_objects otype, int init)
return -EBADF;
}
/* Uninitialized objects are not owned by anyone. However if an
* object is initialized, and the caller is from userspace, then
* we need to assert that the user thread has sufficient permissions
* to re-initialize.
/* Manipulation of any kernel objects by a user thread requires that
* thread be granted access first, even for uninitialized objects
*/
if (ko->flags & K_OBJ_FLAG_INITIALIZED && _is_thread_user() &&
!test_thread_perms(ko)) {
if (_is_thread_user() && !test_thread_perms(ko)) {
printk("thread %p (%d) does not have permission on %s %p [",
_current, _current->base.perm_index, otype_to_str(otype),
obj);