From patchwork Tue Mar 28 23:46:46 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Micka=C3=ABl_Sala=C3=BCn?= X-Patchwork-Id: 9650657 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id DD272601D7 for ; Tue, 28 Mar 2017 23:48:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D2FEC28451 for ; Tue, 28 Mar 2017 23:48:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C744928458; Tue, 28 Mar 2017 23:48:49 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id 72A4B28451 for ; Tue, 28 Mar 2017 23:48:48 +0000 (UTC) Received: (qmail 18111 invoked by uid 550); 28 Mar 2017 23:48:23 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 15962 invoked from network); 28 Mar 2017 23:48:05 -0000 From: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= To: linux-kernel@vger.kernel.org Cc: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= , Alexei Starovoitov , Andy Lutomirski , Arnaldo Carvalho de Melo , Casey Schaufler , Daniel Borkmann , David Drysdale , "David S . Miller" , "Eric W . Biederman" , James Morris , Jann Horn , Jonathan Corbet , Matthew Garrett , Michael Kerrisk , Kees Cook , Paul Moore , Sargun Dhillon , "Serge E . Hallyn" , Shuah Khan , Tejun Heo , Thomas Graf , Will Drewry , kernel-hardening@lists.openwall.com, linux-api@vger.kernel.org, linux-security-module@vger.kernel.org, netdev@vger.kernel.org Date: Wed, 29 Mar 2017 01:46:46 +0200 Message-Id: <20170328234650.19695-8-mic@digikod.net> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170328234650.19695-1-mic@digikod.net> References: <20170328234650.19695-1-mic@digikod.net> MIME-Version: 1.0 X-Antivirus: Dr.Web (R) for Unix mail servers drweb plugin ver.6.0.2.8 X-Antivirus-Code: 0x100000 Subject: [kernel-hardening] [PATCH net-next v6 07/11] landlock: Add ptrace restrictions X-Virus-Scanned: ClamAV using ClamSMTP 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. New in v6 Signed-off-by: Mickaël Salaün Cc: Alexei Starovoitov Cc: Andy Lutomirski Cc: Daniel Borkmann Cc: David S. Miller Cc: James Morris Cc: Kees Cook Cc: Serge E. Hallyn --- security/landlock/Makefile | 2 +- security/landlock/hooks_ptrace.c | 126 +++++++++++++++++++++++++++++++++++++++ security/landlock/hooks_ptrace.h | 11 ++++ security/landlock/init.c | 2 + 4 files changed, 140 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 da8ba8b5183e..099a56ca4842 100644 --- a/security/landlock/Makefile +++ b/security/landlock/Makefile @@ -2,4 +2,4 @@ ccflags-$(CONFIG_SECURITY_LANDLOCK) += -Werror=unused-function obj-$(CONFIG_SECURITY_LANDLOCK) := landlock.o -landlock-y := init.o providers.o hooks.o hooks_fs.o +landlock-y := init.o providers.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..8ab53baba9ad --- /dev/null +++ b/security/landlock/hooks_ptrace.c @@ -0,0 +1,126 @@ +/* + * Landlock LSM - ptrace hooks + * + * Copyright © 2017 Mickaël Salaün + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + */ + +#include +#include /* ARRAY_SIZE */ +#include /* struct landlock_events */ +#include +#include /* struct task_struct */ +#include + +#include "hooks.h" /* landlocked() */ + +#include "hooks_ptrace.h" + + +static bool landlock_events_are_subset(const struct landlock_events *parent, + const struct landlock_events *child) +{ + size_t i; + + if (!parent || !child) + return false; + if (parent == child) + return true; + + for (i = 0; i < ARRAY_SIZE(child->rules); i++) { + struct landlock_rule *walker; + bool found_parent = false; + + if (!parent->rules[i]) + continue; + for (walker = child->rules[i]; walker; walker = walker->prev) { + if (walker == parent->rules[i]) { + found_parent = true; + break; + } + } + if (!found_parent) + return false; + } + return true; +} + +static bool landlock_task_has_subset_events(const struct task_struct *parent, + const struct task_struct *child) +{ +#ifdef CONFIG_SECCOMP_FILTER + if (landlock_events_are_subset(parent->seccomp.landlock_events, + child->seccomp.landlock_events)) + /* must be ANDed with other providers (i.e. cgroup) */ + return true; +#endif /* CONFIG_SECCOMP_FILTER */ + return false; +} + +/** + * landlock_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 rules, then the child must have at least + * the same rules. Else denied. + * + * Determine whether a process may access another, returning 0 if permission + * granted, -errno if denied. + */ +static int landlock_ptrace_access_check(struct task_struct *child, + unsigned int mode) +{ + if (!landlocked(current)) + return 0; + + if (!landlocked(child)) + return -EPERM; + + if (landlock_task_has_subset_events(current, child)) + return 0; + + return -EPERM; +} + +/** + * landlock_ptrace_traceme - determine whether another process may trace the + * current one + * + * @parent: the task proposed to be the tracer + * + * If the parent has Landlock rules, then the current task must have the same + * or more rules. + * 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 landlock_ptrace_traceme(struct task_struct *parent) +{ + if (!landlocked(parent)) + return 0; + + if (!landlocked(current)) + return -EPERM; + + if (landlock_task_has_subset_events(parent, current)) + return 0; + + return -EPERM; +} + +static struct security_hook_list landlock_hooks[] = { + LSM_HOOK_INIT(ptrace_access_check, landlock_ptrace_access_check), + LSM_HOOK_INIT(ptrace_traceme, landlock_ptrace_traceme), +}; + +__init void landlock_add_hooks_ptrace(void) +{ + landlock_register_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks)); +} diff --git a/security/landlock/hooks_ptrace.h b/security/landlock/hooks_ptrace.h new file mode 100644 index 000000000000..15b1f3479e0e --- /dev/null +++ b/security/landlock/hooks_ptrace.h @@ -0,0 +1,11 @@ +/* + * Landlock LSM - ptrace hooks + * + * Copyright © 2017 Mickaël Salaün + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, as + * published by the Free Software Foundation. + */ + +__init void landlock_add_hooks_ptrace(void); diff --git a/security/landlock/init.c b/security/landlock/init.c index ef8a3da69860..c8bce3142a32 100644 --- a/security/landlock/init.c +++ b/security/landlock/init.c @@ -14,6 +14,7 @@ #include #include "hooks_fs.h" +#include "hooks_ptrace.h" static inline bool bpf_landlock_is_valid_access(int off, int size, @@ -137,6 +138,7 @@ void __init landlock_add_hooks(void) { pr_info("landlock: Version %u, ready to sandbox with %s\n", LANDLOCK_VERSION, "seccomp"); + landlock_add_hooks_ptrace(); landlock_add_hooks_fs(); security_add_hooks(NULL, 0, "landlock"); bpf_register_prog_type(&bpf_landlock_type);