|
Message-Id: <20190721213116.23476-8-mic@digikod.net> Date: Sun, 21 Jul 2019 23:31:13 +0200 From: Mickaël Salaün <mic@...ikod.net> To: linux-kernel@...r.kernel.org Cc: Mickaël Salaün <mic@...ikod.net>, Alexander Viro <viro@...iv.linux.org.uk>, Alexei Starovoitov <ast@...nel.org>, Andrew Morton <akpm@...ux-foundation.org>, Andy Lutomirski <luto@...capital.net>, Arnaldo Carvalho de Melo <acme@...nel.org>, Casey Schaufler <casey@...aufler-ca.com>, Daniel Borkmann <daniel@...earbox.net>, David Drysdale <drysdale@...gle.com>, "David S . Miller" <davem@...emloft.net>, "Eric W . Biederman" <ebiederm@...ssion.com>, James Morris <jmorris@...ei.org>, Jann Horn <jann@...jh.net>, John Johansen <john.johansen@...onical.com>, Jonathan Corbet <corbet@....net>, Kees Cook <keescook@...omium.org>, Michael Kerrisk <mtk.manpages@...il.com>, Mickaël Salaün <mickael.salaun@....gouv.fr>, Paul Moore <paul@...l-moore.com>, Sargun Dhillon <sargun@...gun.me>, "Serge E . Hallyn" <serge@...lyn.com>, Shuah Khan <shuah@...nel.org>, Stephen Smalley <sds@...ho.nsa.gov>, Tejun Heo <tj@...nel.org>, Tetsuo Handa <penguin-kernel@...ove.SAKURA.ne.jp>, Thomas Graf <tgraf@...g.ch>, Tycho Andersen <tycho@...ho.ws>, Will Drewry <wad@...omium.org>, kernel-hardening@...ts.openwall.com, linux-api@...r.kernel.org, linux-fsdevel@...r.kernel.org, linux-security-module@...r.kernel.org, netdev@...r.kernel.org Subject: [PATCH bpf-next v10 07/10] landlock: Add ptrace restrictions A landlocked process has less privileges than a non-landlocked process and must then be subject to additional restrictions when manipulating processes. To be allowed to use ptrace(2) and related syscalls on a target process, a landlocked process must have a subset of the target process' rules. Signed-off-by: Mickaël Salaün <mic@...ikod.net> Cc: Alexei Starovoitov <ast@...nel.org> Cc: Andy Lutomirski <luto@...capital.net> Cc: Daniel Borkmann <daniel@...earbox.net> Cc: David S. Miller <davem@...emloft.net> Cc: James Morris <jmorris@...ei.org> Cc: Kees Cook <keescook@...omium.org> Cc: Serge E. Hallyn <serge@...lyn.com> --- Changes since v6: * factor out ptrace check * constify pointers * cleanup headers * use the new security_add_hooks() --- security/landlock/Makefile | 2 +- security/landlock/hooks_ptrace.c | 121 +++++++++++++++++++++++++++++++ security/landlock/hooks_ptrace.h | 8 ++ security/landlock/init.c | 2 + 4 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 security/landlock/hooks_ptrace.c create mode 100644 security/landlock/hooks_ptrace.h diff --git a/security/landlock/Makefile b/security/landlock/Makefile index 270ece5d93de..4500ddb0767e 100644 --- a/security/landlock/Makefile +++ b/security/landlock/Makefile @@ -2,4 +2,4 @@ obj-$(CONFIG_SECURITY_LANDLOCK) := landlock.o landlock-y := init.o \ enforce.o enforce_seccomp.o \ - hooks.o hooks_fs.o + hooks.o hooks_fs.o hooks_ptrace.o diff --git a/security/landlock/hooks_ptrace.c b/security/landlock/hooks_ptrace.c new file mode 100644 index 000000000000..7f5e8b994e93 --- /dev/null +++ b/security/landlock/hooks_ptrace.c @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Landlock LSM - ptrace hooks + * + * Copyright © 2017 Mickaël Salaün <mic@...ikod.net> + */ + +#include <asm/current.h> +#include <linux/errno.h> +#include <linux/kernel.h> /* ARRAY_SIZE */ +#include <linux/lsm_hooks.h> +#include <linux/sched.h> /* struct task_struct */ +#include <linux/seccomp.h> + +#include "common.h" /* struct landlock_prog_set */ +#include "hooks.h" /* landlocked() */ +#include "hooks_ptrace.h" + +static bool progs_are_subset(const struct landlock_prog_set *parent, + const struct landlock_prog_set *child) +{ + size_t i; + + if (!parent || !child) + return false; + if (parent == child) + return true; + + for (i = 0; i < ARRAY_SIZE(child->programs); i++) { + struct landlock_prog_list *walker; + bool found_parent = false; + + if (!parent->programs[i]) + continue; + for (walker = child->programs[i]; walker; + walker = walker->prev) { + if (walker == parent->programs[i]) { + found_parent = true; + break; + } + } + if (!found_parent) + return false; + } + return true; +} + +static bool task_has_subset_progs(const struct task_struct *parent, + const struct task_struct *child) +{ +#ifdef CONFIG_SECCOMP_FILTER + if (progs_are_subset(parent->seccomp.landlock_prog_set, + child->seccomp.landlock_prog_set)) + /* must be ANDed with other providers (i.e. cgroup) */ + return true; +#endif /* CONFIG_SECCOMP_FILTER */ + return false; +} + +static int task_ptrace(const struct task_struct *parent, + const struct task_struct *child) +{ + if (!landlocked(parent)) + return 0; + + if (!landlocked(child)) + return -EPERM; + + if (task_has_subset_progs(parent, child)) + return 0; + + return -EPERM; +} + +/** + * hook_ptrace_access_check - determine whether the current process may access + * another + * + * @child: the process to be accessed + * @mode: the mode of attachment + * + * If the current task has Landlock programs, then the child must have at least + * the same programs. Else denied. + * + * Determine whether a process may access another, returning 0 if permission + * granted, -errno if denied. + */ +static int hook_ptrace_access_check(struct task_struct *child, + unsigned int mode) +{ + return task_ptrace(current, child); +} + +/** + * hook_ptrace_traceme - determine whether another process may trace the + * current one + * + * @parent: the task proposed to be the tracer + * + * If the parent has Landlock programs, then the current task must have the + * same or more programs. + * Else denied. + * + * Determine whether the nominated task is permitted to trace the current + * process, returning 0 if permission is granted, -errno if denied. + */ +static int hook_ptrace_traceme(struct task_struct *parent) +{ + return task_ptrace(parent, current); +} + +static struct security_hook_list landlock_hooks[] = { + LSM_HOOK_INIT(ptrace_access_check, hook_ptrace_access_check), + LSM_HOOK_INIT(ptrace_traceme, hook_ptrace_traceme), +}; + +__init void landlock_add_hooks_ptrace(void) +{ + security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks), + LANDLOCK_NAME); +} diff --git a/security/landlock/hooks_ptrace.h b/security/landlock/hooks_ptrace.h new file mode 100644 index 000000000000..2c2b8a13037f --- /dev/null +++ b/security/landlock/hooks_ptrace.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Landlock LSM - ptrace hooks + * + * Copyright © 2017 Mickaël Salaün <mic@...ikod.net> + */ + +__init void landlock_add_hooks_ptrace(void); diff --git a/security/landlock/init.c b/security/landlock/init.c index eec4467cb5ee..35165fc8a595 100644 --- a/security/landlock/init.c +++ b/security/landlock/init.c @@ -13,6 +13,7 @@ #include "common.h" /* LANDLOCK_* */ #include "hooks_fs.h" +#include "hooks_ptrace.h" static bool bpf_landlock_is_valid_access(int off, int size, enum bpf_access_type type, const struct bpf_prog *prog, @@ -130,6 +131,7 @@ const struct bpf_prog_ops landlock_prog_ops = {}; static int __init landlock_init(void) { pr_info(LANDLOCK_NAME ": Initializing (sandbox with seccomp)\n"); + landlock_add_hooks_ptrace(); landlock_add_hooks_fs(); return 0; } -- 2.22.0
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.