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: Günther Noack <gnoack3000@gmail.com>
Signed-off-by: Mickaël Salaün <mic@digikod.net>
This commit is contained in:
Mickaël Salaün 2025-03-20 20:06:52 +01:00
parent d9d2a68ed4
commit 5b95b329be
No known key found for this signature in database
GPG Key ID: E5E3D0E88C82F6D2
4 changed files with 53 additions and 34 deletions

View File

@ -0,0 +1,48 @@
/* 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 */

View File

@ -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);
}

View File

@ -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
*

View File

@ -19,6 +19,7 @@
#include "common.h"
#include "cred.h"
#include "domain.h"
#include "fs.h"
#include "ruleset.h"
#include "setup.h"