From patchwork Mon Nov 27 17:18:35 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Djalal Harouni X-Patchwork-Id: 10077657 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 B365C602BC for ; Mon, 27 Nov 2017 17:20:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9537E28CA3 for ; Mon, 27 Nov 2017 17:20:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8856C28E4E; Mon, 27 Nov 2017 17:20:34 +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.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED,FREEMAIL_FROM,RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=unavailable 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 E64DF28CA3 for ; Mon, 27 Nov 2017 17:20:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932206AbdK0RTT (ORCPT ); Mon, 27 Nov 2017 12:19:19 -0500 Received: from mail-wm0-f67.google.com ([74.125.82.67]:46583 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753773AbdK0RTN (ORCPT ); Mon, 27 Nov 2017 12:19:13 -0500 Received: by mail-wm0-f67.google.com with SMTP id u83so35866432wmb.5; Mon, 27 Nov 2017 09:19:12 -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=iDvvJ1JYnDduZRCoBQfGyFwA6kMXuKxwHPeddDtjMoI=; b=TlzPoVPyUM8g92nxwyLsSdSq0UJq1hZM/SWTwujk7EiEDNPDqt+sDotVw0N0VHs8kD zTUxptzxIaD60wVf9QPf1luEWaqS2RLWctcY0a970E45YMrIqAA7GxpQ6YyaxnYSFMve oDwmFSHhyNzXT9RT9Th9R/U5fNvS3tMTIaki5XBw6CA308ittxO1ZX1pm/mkQR+Nw0/X MmHnF21GUINXHMNLThKNCZKDy8r12Cf7Z4zMaKEAWxXyxvBOiGCQlkvC2YyqHAKum1xj FSaG0aRVzc6OayiIltbHYF9PjrbdK1edtJpjqSsEJqeWJ5Mm0V5+oSBfpiOzDjxf/BkI fZYQ== 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=iDvvJ1JYnDduZRCoBQfGyFwA6kMXuKxwHPeddDtjMoI=; b=jEb9yEuwj22lmEwBJI4Jenpg2dEoxtgXDSGsskA0ARUN1HDcfBrOxTLJPhnDaFzMRf Syhd6R4GtHm53CQSXwb53egddIjmdC9wrcpRcoguN4NAIhiGlWJTShFCzlLusZdFdLJC Nms+nBBvC0EWv+2sQOdzApL61aecgLqEKXat71r0N9ekQkDUmC0ELeCZUMaeuS9n4xxc dhxX3s+s2+PyvpfuYSgcIkHJN1lqgrhCk7g8asEjQBX8m8VSRNdEQexKrzqD1Uhz/Xgc DsSuYRe1ne9ffhHI0AYeuFKZ63TgDJl6sXM8wSoXEeCmpvq2o/QcZnpNI4CdII/7JGbJ MASw== X-Gm-Message-State: AJaThX5Mnn6VUNgUEvS0zho/NFKEXRou/I199YmNrZvMCEG97BK32iIb Rxk7c/AjXm8+nL1ZQSpi3sU= X-Google-Smtp-Source: AGs4zMZcX1C4F7xBGP0FFQPY1mEdBEcs7ZIUKuSH/T1tZk1RR0k6sTjHO+rPdffhVX0NOLvyqLaV9g== X-Received: by 10.80.244.132 with SMTP id s4mr53552844edm.294.1511803151917; Mon, 27 Nov 2017 09:19:11 -0800 (PST) Received: from localhost.localdomain (ip-109-45-1-111.web.vodafone.de. [109.45.1.111]) by smtp.gmail.com with ESMTPSA id z56sm19356496edb.72.2017.11.27.09.19.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 27 Nov 2017 09:19:11 -0800 (PST) From: Djalal Harouni To: Kees Cook , Andy Lutomirski , Andrew Morton , "Luis R. Rodriguez" , James Morris , Ben Hutchings , Solar Designer , Serge Hallyn , Jessica Yu , Rusty Russell , linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org, kernel-hardening@lists.openwall.com Cc: Jonathan Corbet , Ingo Molnar , "David S. Miller" , netdev@vger.kernel.org, Peter Zijlstra , Linus Torvalds , Djalal Harouni Subject: [PATCH v5 next 2/5] modules:capabilities: add cap_kernel_module_request() permission check Date: Mon, 27 Nov 2017 18:18:35 +0100 Message-Id: <1511803118-2552-3-git-send-email-tixxdz@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1511803118-2552-1-git-send-email-tixxdz@gmail.com> References: <1511803118-2552-1-git-send-email-tixxdz@gmail.com> Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: X-Virus-Scanned: ClamAV using ClamSMTP This is a preparation patch to improve for the module auto-load infrastrucutre. With this change, subsystems that want to autoload modules and implement onsite capability checks, can defer the checks to the capability subsystem by passing the required capabilities with the appropriate modules alias. The capability subsystem will trust callers about the passed values and perform a capability check to either allow module auto-loading or deny it. This patch changes: * Adds cap_kernel_module_request() capability hook. * Adds an empty may_autoload_module() that will be updated in the next patch. Cc: James Morris Cc: Serge Hallyn Cc: Andy Lutomirski Cc: Ben Hutchings Suggested-by: Rusty Russell Suggested-by: Kees Cook Signed-off-by: Djalal Harouni --- include/linux/module.h | 10 ++++++++++ include/linux/security.h | 4 +++- kernel/module.c | 23 +++++++++++++++++++++++ security/commoncap.c | 26 ++++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 1 deletion(-) diff --git a/include/linux/module.h b/include/linux/module.h index c69b49a..5cbb239 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -497,6 +497,10 @@ bool __is_module_percpu_address(unsigned long addr, unsigned long *can_addr); bool is_module_percpu_address(unsigned long addr); bool is_module_text_address(unsigned long addr); +/* Determine whether a module auto-load operation is permitted. */ +int may_autoload_module(char *kmod_name, int required_cap, + const char *kmod_prefix); + static inline bool within_module_core(unsigned long addr, const struct module *mod) { @@ -643,6 +647,12 @@ bool is_module_sig_enforced(void); #else /* !CONFIG_MODULES... */ +static inline int may_autoload_module(char *kmod_name, int required_cap, + const char *kmod_prefix) +{ + return -ENOSYS; +} + static inline struct module *__module_address(unsigned long addr) { return NULL; diff --git a/include/linux/security.h b/include/linux/security.h index 41e700a..9bb53b5 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -102,6 +102,8 @@ extern int cap_task_setscheduler(struct task_struct *p); extern int cap_task_setioprio(struct task_struct *p, int ioprio); extern int cap_task_setnice(struct task_struct *p, int nice); extern int cap_vm_enough_memory(struct mm_struct *mm, long pages); +extern int cap_kernel_module_request(char *kmod_name, int required_cap, + const char *kmod_prefix); struct msghdr; struct sk_buff; @@ -924,7 +926,7 @@ static inline int security_kernel_module_request(char *kmod_name, int required_cap, const char *prefix) { - return 0; + return cap_kernel_module_request(kmod_name, required_cap, prefix); } static inline int security_kernel_read_file(struct file *file, diff --git a/kernel/module.c b/kernel/module.c index f0411a2..3380d39 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -4340,6 +4340,29 @@ struct module *__module_text_address(unsigned long addr) } EXPORT_SYMBOL_GPL(__module_text_address); +/** + * may_autoload_module - Determine whether a module auto-load operation + * is permitted + * @kmod_name: The module name + * @required_cap: if positive, may allow to auto-load the module if this + * capability is set + * @kmod_prefix: The module prefix if any, otherwise NULL + * + * Determine whether a module auto-load operation is allowed or not. + * + * This allows to have more control on automatic module loading, and align it + * with explicit load/unload module operations. The kernel contains several + * modules, some of them are not updated often and may contain bugs and + * vulnerabilities. + * + * Returns 0 if the module request is allowed or -EPERM if not. + */ +int may_autoload_module(char *kmod_name, int required_cap, + const char *kmod_prefix) +{ + return 0; +} + /* Don't grab lock, we're oopsing. */ void print_modules(void) { diff --git a/security/commoncap.c b/security/commoncap.c index 4f8e093..236e573 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -1340,6 +1340,31 @@ int cap_mmap_file(struct file *file, unsigned long reqprot, return 0; } +/** + * cap_kernel_module_request - Determine whether a module auto-load is permitted + * @kmod_name: The module name + * @required_cap: if positive, may allow to auto-load the module if this + * capability is set + * @kmod_prefix: the module prefix if any, otherwise NULL + * + * Determine whether a module should be automatically loaded. + * Returns 0 if the module request should be allowed, -EPERM if not. + */ +int cap_kernel_module_request(char *kmod_name, int required_cap, + const char *kmod_prefix) +{ + int ret; + char comm[sizeof(current->comm)]; + + ret = may_autoload_module(kmod_name, required_cap, kmod_prefix); + if (ret < 0) + pr_notice_ratelimited( + "module: automatic module loading of %.64s by \"%s\"[%d] was denied\n", + kmod_name, get_task_comm(comm, current), current->pid); + + return ret; +} + #ifdef CONFIG_SECURITY struct security_hook_list capability_hooks[] __lsm_ro_after_init = { @@ -1361,6 +1386,7 @@ struct security_hook_list capability_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(task_setioprio, cap_task_setioprio), LSM_HOOK_INIT(task_setnice, cap_task_setnice), LSM_HOOK_INIT(vm_enough_memory, cap_vm_enough_memory), + LSM_HOOK_INIT(kernel_module_request, cap_kernel_module_request), }; void __init capability_add_hooks(void)