Skip to content

Commit 385975d

Browse files
l0kodJames Morris
authored and
James Morris
committed
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 <[email protected]> Signed-off-by: Mickaël Salaün <[email protected]> Reviewed-by: Jann Horn <[email protected]> Acked-by: Serge Hallyn <[email protected]> Reviewed-by: Kees Cook <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: James Morris <[email protected]>
1 parent ae271c1 commit 385975d

File tree

7 files changed

+178
-6
lines changed

7 files changed

+178
-6
lines changed

security/Kconfig

+5-5
Original file line numberDiff line numberDiff line change
@@ -278,11 +278,11 @@ endchoice
278278

279279
config LSM
280280
string "Ordered list of enabled LSMs"
281-
default "lockdown,yama,loadpin,safesetid,integrity,smack,selinux,tomoyo,apparmor,bpf" if DEFAULT_SECURITY_SMACK
282-
default "lockdown,yama,loadpin,safesetid,integrity,apparmor,selinux,smack,tomoyo,bpf" if DEFAULT_SECURITY_APPARMOR
283-
default "lockdown,yama,loadpin,safesetid,integrity,tomoyo,bpf" if DEFAULT_SECURITY_TOMOYO
284-
default "lockdown,yama,loadpin,safesetid,integrity,bpf" if DEFAULT_SECURITY_DAC
285-
default "lockdown,yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor,bpf"
281+
default "landlock,lockdown,yama,loadpin,safesetid,integrity,smack,selinux,tomoyo,apparmor,bpf" if DEFAULT_SECURITY_SMACK
282+
default "landlock,lockdown,yama,loadpin,safesetid,integrity,apparmor,selinux,smack,tomoyo,bpf" if DEFAULT_SECURITY_APPARMOR
283+
default "landlock,lockdown,yama,loadpin,safesetid,integrity,tomoyo,bpf" if DEFAULT_SECURITY_TOMOYO
284+
default "landlock,lockdown,yama,loadpin,safesetid,integrity,bpf" if DEFAULT_SECURITY_DAC
285+
default "landlock,lockdown,yama,loadpin,safesetid,integrity,selinux,smack,tomoyo,apparmor,bpf"
286286
help
287287
A comma-separated list of LSMs, in initialization order.
288288
Any LSMs left off this list will be ignored. This can be

security/landlock/Makefile

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
obj-$(CONFIG_SECURITY_LANDLOCK) := landlock.o
22

3-
landlock-y := object.o ruleset.o
3+
landlock-y := setup.o object.o ruleset.o \
4+
cred.o

security/landlock/common.h

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/*
3+
* Landlock LSM - Common constants and helpers
4+
*
5+
* Copyright © 2016-2020 Mickaël Salaün <[email protected]>
6+
* Copyright © 2018-2020 ANSSI
7+
*/
8+
9+
#ifndef _SECURITY_LANDLOCK_COMMON_H
10+
#define _SECURITY_LANDLOCK_COMMON_H
11+
12+
#define LANDLOCK_NAME "landlock"
13+
14+
#ifdef pr_fmt
15+
#undef pr_fmt
16+
#endif
17+
18+
#define pr_fmt(fmt) LANDLOCK_NAME ": " fmt
19+
20+
#endif /* _SECURITY_LANDLOCK_COMMON_H */

security/landlock/cred.c

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/*
3+
* Landlock LSM - Credential hooks
4+
*
5+
* Copyright © 2017-2020 Mickaël Salaün <[email protected]>
6+
* Copyright © 2018-2020 ANSSI
7+
*/
8+
9+
#include <linux/cred.h>
10+
#include <linux/lsm_hooks.h>
11+
12+
#include "common.h"
13+
#include "cred.h"
14+
#include "ruleset.h"
15+
#include "setup.h"
16+
17+
static int hook_cred_prepare(struct cred *const new,
18+
const struct cred *const old, const gfp_t gfp)
19+
{
20+
struct landlock_ruleset *const old_dom = landlock_cred(old)->domain;
21+
22+
if (old_dom) {
23+
landlock_get_ruleset(old_dom);
24+
landlock_cred(new)->domain = old_dom;
25+
}
26+
return 0;
27+
}
28+
29+
static void hook_cred_free(struct cred *const cred)
30+
{
31+
struct landlock_ruleset *const dom = landlock_cred(cred)->domain;
32+
33+
if (dom)
34+
landlock_put_ruleset_deferred(dom);
35+
}
36+
37+
static struct security_hook_list landlock_hooks[] __lsm_ro_after_init = {
38+
LSM_HOOK_INIT(cred_prepare, hook_cred_prepare),
39+
LSM_HOOK_INIT(cred_free, hook_cred_free),
40+
};
41+
42+
__init void landlock_add_cred_hooks(void)
43+
{
44+
security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks),
45+
LANDLOCK_NAME);
46+
}

security/landlock/cred.h

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/*
3+
* Landlock LSM - Credential hooks
4+
*
5+
* Copyright © 2019-2020 Mickaël Salaün <[email protected]>
6+
* Copyright © 2019-2020 ANSSI
7+
*/
8+
9+
#ifndef _SECURITY_LANDLOCK_CRED_H
10+
#define _SECURITY_LANDLOCK_CRED_H
11+
12+
#include <linux/cred.h>
13+
#include <linux/init.h>
14+
#include <linux/rcupdate.h>
15+
16+
#include "ruleset.h"
17+
#include "setup.h"
18+
19+
struct landlock_cred_security {
20+
struct landlock_ruleset *domain;
21+
};
22+
23+
static inline struct landlock_cred_security *landlock_cred(
24+
const struct cred *cred)
25+
{
26+
return cred->security + landlock_blob_sizes.lbs_cred;
27+
}
28+
29+
static inline const struct landlock_ruleset *landlock_get_current_domain(void)
30+
{
31+
return landlock_cred(current_cred())->domain;
32+
}
33+
34+
/*
35+
* The call needs to come from an RCU read-side critical section.
36+
*/
37+
static inline const struct landlock_ruleset *landlock_get_task_domain(
38+
const struct task_struct *const task)
39+
{
40+
return landlock_cred(__task_cred(task))->domain;
41+
}
42+
43+
static inline bool landlocked(const struct task_struct *const task)
44+
{
45+
bool has_dom;
46+
47+
if (task == current)
48+
return !!landlock_get_current_domain();
49+
50+
rcu_read_lock();
51+
has_dom = !!landlock_get_task_domain(task);
52+
rcu_read_unlock();
53+
return has_dom;
54+
}
55+
56+
__init void landlock_add_cred_hooks(void);
57+
58+
#endif /* _SECURITY_LANDLOCK_CRED_H */

security/landlock/setup.c

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/*
3+
* Landlock LSM - Security framework setup
4+
*
5+
* Copyright © 2016-2020 Mickaël Salaün <[email protected]>
6+
* Copyright © 2018-2020 ANSSI
7+
*/
8+
9+
#include <linux/init.h>
10+
#include <linux/lsm_hooks.h>
11+
12+
#include "common.h"
13+
#include "cred.h"
14+
#include "setup.h"
15+
16+
struct lsm_blob_sizes landlock_blob_sizes __lsm_ro_after_init = {
17+
.lbs_cred = sizeof(struct landlock_cred_security),
18+
};
19+
20+
static int __init landlock_init(void)
21+
{
22+
landlock_add_cred_hooks();
23+
pr_info("Up and running.\n");
24+
return 0;
25+
}
26+
27+
DEFINE_LSM(LANDLOCK_NAME) = {
28+
.name = LANDLOCK_NAME,
29+
.init = landlock_init,
30+
.blobs = &landlock_blob_sizes,
31+
};

security/landlock/setup.h

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/*
3+
* Landlock LSM - Security framework setup
4+
*
5+
* Copyright © 2016-2020 Mickaël Salaün <[email protected]>
6+
* Copyright © 2018-2020 ANSSI
7+
*/
8+
9+
#ifndef _SECURITY_LANDLOCK_SETUP_H
10+
#define _SECURITY_LANDLOCK_SETUP_H
11+
12+
#include <linux/lsm_hooks.h>
13+
14+
extern struct lsm_blob_sizes landlock_blob_sizes;
15+
16+
#endif /* _SECURITY_LANDLOCK_SETUP_H */

0 commit comments

Comments
 (0)