Commit 385975dc authored by Mickaël Salaün's avatar Mickaël Salaün Committed by James Morris
Browse files

landlock: Set up the security framework and manage credentials



Process's credentials point to a Landlock domain, which is underneath
implemented with a ruleset.  In the following commits, this domain is
used to check and enforce the ptrace and filesystem security policies.
A domain is inherited from a parent to its child the same way a thread
inherits a seccomp policy.

Cc: James Morris <jmorris@namei.org>
Signed-off-by: default avatarMickaël Salaün <mic@linux.microsoft.com>
Reviewed-by: default avatarJann Horn <jannh@google.com>
Acked-by: default avatarSerge Hallyn <serge@hallyn.com>
Reviewed-by: default avatarKees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/20210422154123.13086-4-mic@digikod.net


Signed-off-by: default avatarJames Morris <jamorris@linux.microsoft.com>
parent ae271c1b
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -278,11 +278,11 @@ endchoice

config LSM
	string "Ordered list of enabled LSMs"
	default "lockdown,yama,loadpin,safesetid,integrity,smack,selinux,tomoyo,apparmor,bpf" if DEFAULT_SECURITY_SMACK
	default "lockdown,yama,loadpin,safesetid,integrity,apparmor,selinux,smack,tomoyo,bpf" if DEFAULT_SECURITY_APPARMOR
	default "lockdown,yama,loadpin,safesetid,integrity,tomoyo,bpf" if DEFAULT_SECURITY_TOMOYO
	default "lockdown,yama,loadpin,safesetid,integrity,bpf" if DEFAULT_SECURITY_DAC
	default "lockdown,yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor,bpf"
	default "landlock,lockdown,yama,loadpin,safesetid,integrity,smack,selinux,tomoyo,apparmor,bpf" if DEFAULT_SECURITY_SMACK
	default "landlock,lockdown,yama,loadpin,safesetid,integrity,apparmor,selinux,smack,tomoyo,bpf" if DEFAULT_SECURITY_APPARMOR
	default "landlock,lockdown,yama,loadpin,safesetid,integrity,tomoyo,bpf" if DEFAULT_SECURITY_TOMOYO
	default "landlock,lockdown,yama,loadpin,safesetid,integrity,bpf" if DEFAULT_SECURITY_DAC
	default "landlock,lockdown,yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor,bpf"
	help
	  A comma-separated list of LSMs, in initialization order.
	  Any LSMs left off this list will be ignored. This can be
+2 −1
Original line number Diff line number Diff line
obj-$(CONFIG_SECURITY_LANDLOCK) := landlock.o

landlock-y := object.o ruleset.o
landlock-y := setup.o object.o ruleset.o \
	cred.o
+20 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Landlock LSM - Common constants and helpers
 *
 * Copyright © 2016-2020 Mickaël Salaün <mic@digikod.net>
 * Copyright © 2018-2020 ANSSI
 */

#ifndef _SECURITY_LANDLOCK_COMMON_H
#define _SECURITY_LANDLOCK_COMMON_H

#define LANDLOCK_NAME "landlock"

#ifdef pr_fmt
#undef pr_fmt
#endif

#define pr_fmt(fmt) LANDLOCK_NAME ": " fmt

#endif /* _SECURITY_LANDLOCK_COMMON_H */
+46 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Landlock LSM - Credential hooks
 *
 * Copyright © 2017-2020 Mickaël Salaün <mic@digikod.net>
 * Copyright © 2018-2020 ANSSI
 */

#include <linux/cred.h>
#include <linux/lsm_hooks.h>

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

static int hook_cred_prepare(struct cred *const new,
		const struct cred *const old, const gfp_t gfp)
{
	struct landlock_ruleset *const old_dom = landlock_cred(old)->domain;

	if (old_dom) {
		landlock_get_ruleset(old_dom);
		landlock_cred(new)->domain = old_dom;
	}
	return 0;
}

static void hook_cred_free(struct cred *const cred)
{
	struct landlock_ruleset *const dom = landlock_cred(cred)->domain;

	if (dom)
		landlock_put_ruleset_deferred(dom);
}

static struct security_hook_list landlock_hooks[] __lsm_ro_after_init = {
	LSM_HOOK_INIT(cred_prepare, hook_cred_prepare),
	LSM_HOOK_INIT(cred_free, hook_cred_free),
};

__init void landlock_add_cred_hooks(void)
{
	security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks),
			LANDLOCK_NAME);
}
+58 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Landlock LSM - Credential hooks
 *
 * Copyright © 2019-2020 Mickaël Salaün <mic@digikod.net>
 * Copyright © 2019-2020 ANSSI
 */

#ifndef _SECURITY_LANDLOCK_CRED_H
#define _SECURITY_LANDLOCK_CRED_H

#include <linux/cred.h>
#include <linux/init.h>
#include <linux/rcupdate.h>

#include "ruleset.h"
#include "setup.h"

struct landlock_cred_security {
	struct landlock_ruleset *domain;
};

static inline struct landlock_cred_security *landlock_cred(
		const struct cred *cred)
{
	return cred->security + landlock_blob_sizes.lbs_cred;
}

static inline const struct landlock_ruleset *landlock_get_current_domain(void)
{
	return landlock_cred(current_cred())->domain;
}

/*
 * The call needs to come from an RCU read-side critical section.
 */
static inline const struct landlock_ruleset *landlock_get_task_domain(
		const struct task_struct *const task)
{
	return landlock_cred(__task_cred(task))->domain;
}

static inline bool landlocked(const struct task_struct *const task)
{
	bool has_dom;

	if (task == current)
		return !!landlock_get_current_domain();

	rcu_read_lock();
	has_dom = !!landlock_get_task_domain(task);
	rcu_read_unlock();
	return has_dom;
}

__init void landlock_add_cred_hooks(void);

#endif /* _SECURITY_LANDLOCK_CRED_H */
Loading