From patchwork Thu Feb 2 17:04:52 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Djalal Harouni X-Patchwork-Id: 9552539 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 81BAA602F0 for ; Thu, 2 Feb 2017 17:06:28 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 76D081FFC9 for ; Thu, 2 Feb 2017 17:06:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6B7B9284A3; Thu, 2 Feb 2017 17:06:28 +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=-6.3 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EF26C1FFC9 for ; Thu, 2 Feb 2017 17:06:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751875AbdBBRG1 (ORCPT ); Thu, 2 Feb 2017 12:06:27 -0500 Received: from mail-wm0-f66.google.com ([74.125.82.66]:35992 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751618AbdBBRFd (ORCPT ); Thu, 2 Feb 2017 12:05:33 -0500 Received: by mail-wm0-f66.google.com with SMTP id r18so14332245wmd.3; Thu, 02 Feb 2017 09:05:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=AdQqnk6l72JndWplWyfsWnwOdyAenl95cjo+09k82Kc=; b=Tqtt13znQ+vRL8F7F3nLpQLPF336Ka6joGp25fPxE1iVB9PqQ7+86RCRYmwC8y2vPO nRKf1Y2lssN/6De9RPKLWgNB7Af3ILZcXNCMjT9h34lWAb1bAoznx1oWAITRCjOPxdiI a1lgj1nDKYbO5iZLlDOjo8LYBDCLEepjeIzVDWUt/HnH7kpA8EWtcZO3na/aQaQtQfeA Tl0wvflUwt8hnv7LQvpaVBs8d5m8vtse7cawyjg2sAbAmDPwHA9GVcY1aPNgD8Ytskdw Q+Tz542AbbLcZbeHXm/2ZIiCR8/sCySp71pQZhz2IuMDQkc02uof11Jo3kIdrplBLnms A/BQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=AdQqnk6l72JndWplWyfsWnwOdyAenl95cjo+09k82Kc=; b=nZm88ici3V2ffU4qaplj/ThwSamY8zv4fd0tKon3JaGyfb90qVRT3UpyhKQOJKVu1K KTxEtlkTZYDMMqpotqN8T79jW9sriyW1lNcWgxSfMiVmVD94FyJ5StfGxhd9z+lvKqEK 6cm/bDh/xsRXPUn6LSyBtwtdA7khLS9E47kNhe2cMOXwhbqZ4816pDc5vAUkDrB55mfk yD1fUDHsKSm9xJMz5iamdZti9/1IyycVDan7fZnksJ6M71KSGUC5HbaN4JtqVL8+6Kh/ m6bi/GRRDD0izdt2yyFg7a7Khhgr1ewaPWM41JOh8UCWKRAvRANczmDV+jvxtNNYCoiT 7fZg== X-Gm-Message-State: AIkVDXJYB6QE5xTIQmKhnRN2OIIyKTRAi4x7CkN774BTWl9o1ywCtxXXIZHwPhm20zYCkA== X-Received: by 10.28.185.77 with SMTP id j74mr8877866wmf.76.1486055132060; Thu, 02 Feb 2017 09:05:32 -0800 (PST) Received: from dztty2.localdomain (ip5b41f4e7.dynamic.kabel-deutschland.de. [91.65.244.231]) by smtp.gmail.com with ESMTPSA id 8sm4805059wmg.1.2017.02.02.09.05.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 02 Feb 2017 09:05:31 -0800 (PST) From: Djalal Harouni X-Google-Original-From: Djalal Harouni To: linux-kernel@vger.kernel.org, kernel-hardening@lists.openwall.com, linux-security-module@vger.kernel.org, Kees Cook Cc: Andrew Morton , Lafcadio Wluiki , Djalal Harouni , Dongsu Park , Andy Lutomirski , James Morris , , Al Viro , Daniel Mack , Jann Horn , Elena Reshetova Subject: [RFC/PATCH 1/3] security: add the security_task_copy() hook Date: Thu, 2 Feb 2017 18:04:52 +0100 Message-Id: <1486055094-4532-2-git-send-email-djalal@gmail.com> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1486055094-4532-1-git-send-email-djalal@gmail.com> References: <1486055094-4532-1-git-send-email-djalal@gmail.com> Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: X-Virus-Scanned: ClamAV using ClamSMTP From: Djalal Harouni This hook is needed by Timgad LSM. Timgad uses a sysctl and a per-process prctl() interface to control which processes are allowed to load and unload modules. However to achieve that we need new hooks to save the context of tasks. Sadly there is no way, if we want to add new LSMs we are faced with two choices: 1) Either fight and collide we other major LSMs since all of them they do save their context on the same shared security structs. 2) If we want our module to be a minor stackable LSM, that can be used easily without any pain, we have to find a new way to store our context. Our use case is more in the seccomp logic, we want to add or fix a gap that seccomp can not handle. At the same time we want to keep the interface as easy as possible for userspace sandboxing. After some years it seems like a good easy security feature for userspace should apply at the same time when we apply: seccomp filters and the no_new_privs flag. To achieve the above we add the security_task_copy() hook that allows us to clone the Timgad context of parent into child task_struct. The security hook can also be used by new LSMs after the child task has done some initialization, this way they won't clash with the major LSMs. The situation is not really well, this hook allows us to introduce a stackable LSM that can be easily used with all other LSMs. Cc: Kees Cook Signed-off-by: Djalal Harouni --- include/linux/lsm_hooks.h | 2 ++ include/linux/security.h | 6 ++++++ kernel/fork.c | 4 ++++ security/security.c | 6 ++++++ 4 files changed, 18 insertions(+) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 558adfa..b37e35e 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -1479,6 +1479,7 @@ union security_list_options { int (*file_open)(struct file *file, const struct cred *cred); int (*task_create)(unsigned long clone_flags); + int (*task_copy)(struct task_struct *task); void (*task_free)(struct task_struct *task); int (*cred_alloc_blank)(struct cred *cred, gfp_t gfp); void (*cred_free)(struct cred *cred); @@ -1745,6 +1746,7 @@ struct security_hook_heads { struct list_head file_receive; struct list_head file_open; struct list_head task_create; + struct list_head task_copy; struct list_head task_free; struct list_head cred_alloc_blank; struct list_head cred_free; diff --git a/include/linux/security.h b/include/linux/security.h index c2125e9..748058e 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -305,6 +305,7 @@ int security_file_send_sigiotask(struct task_struct *tsk, int security_file_receive(struct file *file); int security_file_open(struct file *file, const struct cred *cred); int security_task_create(unsigned long clone_flags); +int security_task_copy(struct task_struct *task); void security_task_free(struct task_struct *task); int security_cred_alloc_blank(struct cred *cred, gfp_t gfp); void security_cred_free(struct cred *cred); @@ -857,6 +858,11 @@ static inline int security_task_create(unsigned long clone_flags) return 0; } +static inline int security_task_copy(struct task_struct *task) +{ + return 0; +} + static inline void security_task_free(struct task_struct *task) { } diff --git a/kernel/fork.c b/kernel/fork.c index 11c5c8a..81c29d8 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1746,6 +1746,10 @@ static __latent_entropy struct task_struct *copy_process( if (retval) goto bad_fork_free_pid; + retval = security_task_copy(p); + if (retval) + goto bad_fork_cancel_cgroup; + /* * Make it visible to the rest of the system, but dont wake it up yet. * Need tasklist lock for parent etc handling! diff --git a/security/security.c b/security/security.c index f825304..5c699c8 100644 --- a/security/security.c +++ b/security/security.c @@ -892,6 +892,11 @@ int security_task_create(unsigned long clone_flags) return call_int_hook(task_create, 0, clone_flags); } +int security_task_copy(struct task_struct *task) +{ + return call_int_hook(task_copy, 0, task); +} + void security_task_free(struct task_struct *task) { call_void_hook(task_free, task); @@ -1731,6 +1736,7 @@ struct security_hook_heads security_hook_heads = { .file_receive = LIST_HEAD_INIT(security_hook_heads.file_receive), .file_open = LIST_HEAD_INIT(security_hook_heads.file_open), .task_create = LIST_HEAD_INIT(security_hook_heads.task_create), + .task_copy = LIST_HEAD_INIT(security_hook_heads.task_copy), .task_free = LIST_HEAD_INIT(security_hook_heads.task_free), .cred_alloc_blank = LIST_HEAD_INIT(security_hook_heads.cred_alloc_blank),