linux/security/landlock/ruleset.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Landlock LSM - Ruleset management
 *
 * Copyright © 2016-2020 Mickaël Salaün <[email protected]>
 * Copyright © 2018-2020 ANSSI
 */

#include <linux/bits.h>
#include <linux/bug.h>
#include <linux/compiler_types.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/lockdep.h>
#include <linux/overflow.h>
#include <linux/rbtree.h>
#include <linux/refcount.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>

#include "limits.h"
#include "object.h"
#include "ruleset.h"

static struct landlock_ruleset *create_ruleset(const u32 num_layers)
{}

struct landlock_ruleset *
landlock_create_ruleset(const access_mask_t fs_access_mask,
			const access_mask_t net_access_mask)
{}

static void build_check_rule(void)
{}

static bool is_object_pointer(const enum landlock_key_type key_type)
{}

static struct landlock_rule *
create_rule(const struct landlock_id id,
	    const struct landlock_layer (*const layers)[], const u32 num_layers,
	    const struct landlock_layer *const new_layer)
{}

static struct rb_root *get_root(struct landlock_ruleset *const ruleset,
				const enum landlock_key_type key_type)
{}

static void free_rule(struct landlock_rule *const rule,
		      const enum landlock_key_type key_type)
{}

static void build_check_ruleset(void)
{}

/**
 * insert_rule - Create and insert a rule in a ruleset
 *
 * @ruleset: The ruleset to be updated.
 * @id: The ID to build the new rule with.  The underlying kernel object, if
 *      any, must be held by the caller.
 * @layers: One or multiple layers to be copied into the new rule.
 * @num_layers: The number of @layers entries.
 *
 * When user space requests to add a new rule to a ruleset, @layers only
 * contains one entry and this entry is not assigned to any level.  In this
 * case, the new rule will extend @ruleset, similarly to a boolean OR between
 * access rights.
 *
 * When merging a ruleset in a domain, or copying a domain, @layers will be
 * added to @ruleset as new constraints, similarly to a boolean AND between
 * access rights.
 */
static int insert_rule(struct landlock_ruleset *const ruleset,
		       const struct landlock_id id,
		       const struct landlock_layer (*const layers)[],
		       const size_t num_layers)
{}

static void build_check_layer(void)
{}

/* @ruleset must be locked by the caller. */
int landlock_insert_rule(struct landlock_ruleset *const ruleset,
			 const struct landlock_id id,
			 const access_mask_t access)
{}

static void get_hierarchy(struct landlock_hierarchy *const hierarchy)
{}

static void put_hierarchy(struct landlock_hierarchy *hierarchy)
{}

static int merge_tree(struct landlock_ruleset *const dst,
		      struct landlock_ruleset *const src,
		      const enum landlock_key_type key_type)
{}

static int merge_ruleset(struct landlock_ruleset *const dst,
			 struct landlock_ruleset *const src)
{}

static int inherit_tree(struct landlock_ruleset *const parent,
			struct landlock_ruleset *const child,
			const enum landlock_key_type key_type)
{}

static int inherit_ruleset(struct landlock_ruleset *const parent,
			   struct landlock_ruleset *const child)
{}

static void free_ruleset(struct landlock_ruleset *const ruleset)
{}

void landlock_put_ruleset(struct landlock_ruleset *const ruleset)
{}

static void free_ruleset_work(struct work_struct *const work)
{}

void landlock_put_ruleset_deferred(struct landlock_ruleset *const ruleset)
{}

/**
 * landlock_merge_ruleset - Merge a ruleset with a domain
 *
 * @parent: Parent domain.
 * @ruleset: New ruleset to be merged.
 *
 * Returns the intersection of @parent and @ruleset, or returns @parent if
 * @ruleset is empty, or returns a duplicate of @ruleset if @parent is empty.
 */
struct landlock_ruleset *
landlock_merge_ruleset(struct landlock_ruleset *const parent,
		       struct landlock_ruleset *const ruleset)
{}

/*
 * The returned access has the same lifetime as @ruleset.
 */
const struct landlock_rule *
landlock_find_rule(const struct landlock_ruleset *const ruleset,
		   const struct landlock_id id)
{}

/*
 * @layer_masks is read and may be updated according to the access request and
 * the matching rule.
 * @masks_array_size must be equal to ARRAY_SIZE(*layer_masks).
 *
 * Returns true if the request is allowed (i.e. relevant layer masks for the
 * request are empty).
 */
bool landlock_unmask_layers(const struct landlock_rule *const rule,
			    const access_mask_t access_request,
			    layer_mask_t (*const layer_masks)[],
			    const size_t masks_array_size)
{}

get_access_mask_t;

/**
 * landlock_init_layer_masks - Initialize layer masks from an access request
 *
 * Populates @layer_masks such that for each access right in @access_request,
 * the bits for all the layers are set where this access right is handled.
 *
 * @domain: The domain that defines the current restrictions.
 * @access_request: The requested access rights to check.
 * @layer_masks: It must contain %LANDLOCK_NUM_ACCESS_FS or
 * %LANDLOCK_NUM_ACCESS_NET elements according to @key_type.
 * @key_type: The key type to switch between access masks of different types.
 *
 * Returns: An access mask where each access right bit is set which is handled
 * in any of the active layers in @domain.
 */
access_mask_t
landlock_init_layer_masks(const struct landlock_ruleset *const domain,
			  const access_mask_t access_request,
			  layer_mask_t (*const layer_masks)[],
			  const enum landlock_key_type key_type)
{}