Unverified Commit 5b95b329 authored by Mickaël Salaün's avatar Mickaël Salaün
Browse files

landlock: Move domain hierarchy management

Create a new domain.h file containing the struct landlock_hierarchy
definition and helpers.  This type will grow with audit support.  This
also prepares for a new domain type.

Cc: Günther Noack <gnoack@google.com>
Link: https://lore.kernel.org/r/20250320190717.2287696-4-mic@digikod.net


Reviewed-by: default avatarGünther Noack <gnoack3000@gmail.com>
Signed-off-by: default avatarMickaël Salaün <mic@digikod.net>
parent d9d2a68e
Loading
Loading
Loading
Loading
+48 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Landlock - Domain management
 *
 * Copyright © 2016-2020 Mickaël Salaün <mic@digikod.net>
 * Copyright © 2018-2020 ANSSI
 */

#ifndef _SECURITY_LANDLOCK_DOMAIN_H
#define _SECURITY_LANDLOCK_DOMAIN_H

#include <linux/mm.h>
#include <linux/refcount.h>

/**
 * struct landlock_hierarchy - Node in a domain hierarchy
 */
struct landlock_hierarchy {
	/**
	 * @parent: Pointer to the parent node, or NULL if it is a root
	 * Landlock domain.
	 */
	struct landlock_hierarchy *parent;
	/**
	 * @usage: Number of potential children domains plus their parent
	 * domain.
	 */
	refcount_t usage;
};

static inline void
landlock_get_hierarchy(struct landlock_hierarchy *const hierarchy)
{
	if (hierarchy)
		refcount_inc(&hierarchy->usage);
}

static inline void landlock_put_hierarchy(struct landlock_hierarchy *hierarchy)
{
	while (hierarchy && refcount_dec_and_test(&hierarchy->usage)) {
		const struct landlock_hierarchy *const freeme = hierarchy;

		hierarchy = hierarchy->parent;
		kfree(freeme);
	}
}

#endif /* _SECURITY_LANDLOCK_DOMAIN_H */
+3 −18
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <linux/workqueue.h>

#include "access.h"
#include "domain.h"
#include "limits.h"
#include "object.h"
#include "ruleset.h"
@@ -307,22 +308,6 @@ int landlock_insert_rule(struct landlock_ruleset *const ruleset,
	return insert_rule(ruleset, id, &layers, ARRAY_SIZE(layers));
}

static void get_hierarchy(struct landlock_hierarchy *const hierarchy)
{
	if (hierarchy)
		refcount_inc(&hierarchy->usage);
}

static void put_hierarchy(struct landlock_hierarchy *hierarchy)
{
	while (hierarchy && refcount_dec_and_test(&hierarchy->usage)) {
		const struct landlock_hierarchy *const freeme = hierarchy;

		hierarchy = hierarchy->parent;
		kfree(freeme);
	}
}

static int merge_tree(struct landlock_ruleset *const dst,
		      struct landlock_ruleset *const src,
		      const enum landlock_key_type key_type)
@@ -477,7 +462,7 @@ static int inherit_ruleset(struct landlock_ruleset *const parent,
		err = -EINVAL;
		goto out_unlock;
	}
	get_hierarchy(parent->hierarchy);
	landlock_get_hierarchy(parent->hierarchy);
	child->hierarchy->parent = parent->hierarchy;

out_unlock:
@@ -501,7 +486,7 @@ static void free_ruleset(struct landlock_ruleset *const ruleset)
		free_rule(freeme, LANDLOCK_KEY_NET_PORT);
#endif /* IS_ENABLED(CONFIG_INET) */

	put_hierarchy(ruleset->hierarchy);
	landlock_put_hierarchy(ruleset->hierarchy);
	kfree(ruleset);
}

+1 −16
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/workqueue.h>

#include "access.h"
#include "domain.h"
#include "limits.h"
#include "object.h"

@@ -108,22 +109,6 @@ struct landlock_rule {
	struct landlock_layer layers[] __counted_by(num_layers);
};

/**
 * struct landlock_hierarchy - Node in a ruleset hierarchy
 */
struct landlock_hierarchy {
	/**
	 * @parent: Pointer to the parent node, or NULL if it is a root
	 * Landlock domain.
	 */
	struct landlock_hierarchy *parent;
	/**
	 * @usage: Number of potential children domains plus their parent
	 * domain.
	 */
	refcount_t usage;
};

/**
 * struct landlock_ruleset - Landlock ruleset
 *
+1 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@

#include "common.h"
#include "cred.h"
#include "domain.h"
#include "fs.h"
#include "ruleset.h"
#include "setup.h"