linux/security/landlock/object.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Landlock LSM - Object management
   4 *
   5 * Copyright © 2016-2020 Mickaël Salaün <mic@digikod.net>
   6 * Copyright © 2018-2020 ANSSI
   7 */
   8
   9#include <linux/bug.h>
  10#include <linux/compiler_types.h>
  11#include <linux/err.h>
  12#include <linux/kernel.h>
  13#include <linux/rcupdate.h>
  14#include <linux/refcount.h>
  15#include <linux/slab.h>
  16#include <linux/spinlock.h>
  17
  18#include "object.h"
  19
  20struct landlock_object *landlock_create_object(
  21                const struct landlock_object_underops *const underops,
  22                void *const underobj)
  23{
  24        struct landlock_object *new_object;
  25
  26        if (WARN_ON_ONCE(!underops || !underobj))
  27                return ERR_PTR(-ENOENT);
  28        new_object = kzalloc(sizeof(*new_object), GFP_KERNEL_ACCOUNT);
  29        if (!new_object)
  30                return ERR_PTR(-ENOMEM);
  31        refcount_set(&new_object->usage, 1);
  32        spin_lock_init(&new_object->lock);
  33        new_object->underops = underops;
  34        new_object->underobj = underobj;
  35        return new_object;
  36}
  37
  38/*
  39 * The caller must own the object (i.e. thanks to object->usage) to safely put
  40 * it.
  41 */
  42void landlock_put_object(struct landlock_object *const object)
  43{
  44        /*
  45         * The call to @object->underops->release(object) might sleep, e.g.
  46         * because of iput().
  47         */
  48        might_sleep();
  49        if (!object)
  50                return;
  51
  52        /*
  53         * If the @object's refcount cannot drop to zero, we can just decrement
  54         * the refcount without holding a lock. Otherwise, the decrement must
  55         * happen under @object->lock for synchronization with things like
  56         * get_inode_object().
  57         */
  58        if (refcount_dec_and_lock(&object->usage, &object->lock)) {
  59                __acquire(&object->lock);
  60                /*
  61                 * With @object->lock initially held, remove the reference from
  62                 * @object->underobj to @object (if it still exists).
  63                 */
  64                object->underops->release(object);
  65                kfree_rcu(object, rcu_free);
  66        }
  67}
  68