From patchwork Wed Apr 25 08:59:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sargun Dhillon X-Patchwork-Id: 10361915 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 60A8360225 for ; Wed, 25 Apr 2018 08:59:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4CC8528E76 for ; Wed, 25 Apr 2018 08:59:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 411FA28ED2; Wed, 25 Apr 2018 08:59:37 +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_SIGNED, RCVD_IN_DNSWL_HI,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 77FDF28E76 for ; Wed, 25 Apr 2018 08:59:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751274AbeDYI7f (ORCPT ); Wed, 25 Apr 2018 04:59:35 -0400 Received: from mail-it0-f68.google.com ([209.85.214.68]:33120 "EHLO mail-it0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750943AbeDYI7e (ORCPT ); Wed, 25 Apr 2018 04:59:34 -0400 Received: by mail-it0-f68.google.com with SMTP id x144-v6so14723805itc.0 for ; Wed, 25 Apr 2018 01:59:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sargun.me; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=jPsQXXMPYdhZY7S/2+51xUSMiNu8g3yxce9/xSInDgc=; b=MOSzf9AnIsnXCGQXZ5lgx3M+qyqoGU7H45MVBgS3ZDwie2bSFL5o9VE8DEJj7zXt12 rsMBryu7h/kb6S8cBd04pj2TIFoQoxlo8JQbs4uYtUZcIMBxT7hsjTlYgt3v+Hs7PlA9 /UoJ/cjzE2i+jCnvtlEYoCvt1ivAYTSvW/J/M= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=jPsQXXMPYdhZY7S/2+51xUSMiNu8g3yxce9/xSInDgc=; b=B4g0mlV1BP+/NzjlVOgBa7Xmk+kRscssXcGHZav3vwoytjug+77pjts1Z4Pb40MvmH xDJlfTS53vKqDMaMWBqFUMz5hfBJhKdgCPxLk2nU/KsuawrQiEJ4gtTKdLJg5MOmfPHw 6UJG7SXKr4SqCiLOAKeBnBGyDlcygzF+FnTEqrVYObGNdUz1JuDKFkbVgJc905LRCZif FARuhDJtA2MvFOxWK4yLhTGXpB2f3Yib7UsUHsLq8F63zFCF8sw/xJIETVy3OzlJsO2G RfsKowsBtx4KDRjiog3/VYn6PKE8jOT0IiQQrruGHIp0fYDZRkw0wGw+YPxBtlagu6WG 3QrA== X-Gm-Message-State: ALQs6tAGp7/RiQM1qRCjAJyNxQLVaSSk3l4bCBo5vCO0X1z1ljCwrPyx qTjO7NQXrF7p4Rg+FDps9cmOhDUCZvF89g== X-Google-Smtp-Source: AB8JxZoQ4zYd4A94n4P6z+hil9c7hSPW1EapuaR/+0hsurrImp8RPlsz/KwqCQ9HWCZz4ovV6sAjeA== X-Received: by 2002:a24:3989:: with SMTP id l131-v6mr4284786ita.28.1524646773382; Wed, 25 Apr 2018 01:59:33 -0700 (PDT) Received: from ircssh-2.c.rugged-nimbus-611.internal (80.60.198.104.bc.googleusercontent.com. [104.198.60.80]) by smtp.gmail.com with ESMTPSA id t7-v6sm96273ite.35.2018.04.25.01.59.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 25 Apr 2018 01:59:32 -0700 (PDT) Date: Wed, 25 Apr 2018 08:59:31 +0000 From: Sargun Dhillon To: linux-security-module@vger.kernel.org Cc: penguin-kernel@i-love.sakura.ne.jp, keescook@chromium.org, igor.stoppa@huawei.com, casey@schaufler-ca.com, jmorris@namei.org, sds@tycho.nsa.gov, paul@paul-moore.com, plautrba@redhat.com Subject: [PATCH v7 4/6] security: Expose security_add_hooks externally and add error handling Message-ID: <53a2efaab40c11ee79198149f81b6cadf385163d.1524645853.git.sargun@sargun.me> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.24 (2015-08-30) Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: X-Virus-Scanned: ClamAV using ClamSMTP This exports security_add_hooks. In order to safely export it, we need have proper error handling for when mutable hooks are not available, rather than crashing the kernel. It now returns an error if it's unable to get a lock to install hooks. For built-in modules, this should never happen, so by default, they crash the kernel. It is up to 3rd party module authors to handle this case for their own modules. Signed-off-by: Sargun Dhillon --- include/linux/lsm_hooks.h | 7 +++++-- security/apparmor/lsm.c | 2 +- security/commoncap.c | 2 +- security/loadpin/loadpin.c | 2 +- security/security.c | 23 ++++++++++++++++------- security/selinux/hooks.c | 2 +- security/smack/smack_lsm.c | 2 +- security/tomoyo/tomoyo.c | 2 +- security/yama/yama_lsm.c | 2 +- 9 files changed, 28 insertions(+), 16 deletions(-) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 5846b010de0d..c794c8f2f8b9 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -28,7 +28,7 @@ #include #include #include - +#include /** * union security_list_options - Linux Security Module hook function list * @@ -2010,6 +2010,7 @@ struct lsm_info { const char *name; const unsigned int count; struct security_hook_list *hooks; + struct module *owner; } __randomize_layout; struct security_hook_list { @@ -2039,9 +2040,11 @@ struct security_hook_list { .name = NAME, \ .hooks = HOOKS, \ .count = ARRAY_SIZE(HOOKS), \ + .owner = THIS_MODULE, \ } -extern void security_add_hooks(struct lsm_info *lsm, bool is_mutable); +extern int __must_check security_add_hooks(struct lsm_info *lsm, + bool is_mutable); #ifdef CONFIG_SECURITY_SELINUX_DISABLE void security_delete_hooks(struct lsm_info *lsm); diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 85ad007bcb92..6477e9b088b1 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -1564,7 +1564,7 @@ static int __init apparmor_init(void) aa_free_root_ns(); goto buffers_out; } - security_add_hooks(&apparmor_info, false); + BUG_ON(security_add_hooks(&apparmor_info, false)); /* Report that AppArmor successfully initialized */ apparmor_initialized = 1; diff --git a/security/commoncap.c b/security/commoncap.c index 6ce5703075d7..3739e11d02e9 100644 --- a/security/commoncap.c +++ b/security/commoncap.c @@ -1365,7 +1365,7 @@ static struct lsm_info capability_info = void __init capability_add_hooks(void) { - security_add_hooks(&capability_info, false); + BUG_ON(security_add_hooks(&capability_info, false)); } #endif /* CONFIG_SECURITY */ diff --git a/security/loadpin/loadpin.c b/security/loadpin/loadpin.c index c31907ab9724..b0a357034736 100644 --- a/security/loadpin/loadpin.c +++ b/security/loadpin/loadpin.c @@ -183,7 +183,7 @@ static struct lsm_info loadpin_info = LSM_MODULE_INIT("loadpin", loadpin_hooks); void __init loadpin_add_hooks(void) { pr_info("ready to pin (currently %sabled)", enabled ? "en" : "dis"); - security_add_hooks(&loadpin_info, false); + BUG_ON(security_add_hooks(&loadpin_info, false)); } /* Should not be mutable after boot, so not listed in sysfs (perm == 0). */ diff --git a/security/security.c b/security/security.c index 6b090d53bf9d..8d8a227eeeea 100644 --- a/security/security.c +++ b/security/security.c @@ -174,9 +174,9 @@ void security_delete_hooks(struct lsm_info *info) } #endif /* CONFIG_SECURITY_SELINUX_DISABLE */ -static void __init security_add_hook(struct security_hook_list *hook, - struct lsm_info *info, - struct security_hook_heads *heads) +static void security_add_hook(struct security_hook_list *hook, + struct lsm_info *info, + struct security_hook_heads *heads) { const unsigned int offset = hook->offset; const unsigned int idx = offset / sizeof(struct hlist_head); @@ -194,23 +194,32 @@ static void __init security_add_hook(struct security_hook_list *hook, * @is_mutable: Can these hooks be loaded or unloaded after boot time * * Each LSM has to register its hooks with the infrastructure. + * Return 0 on success */ -void __init security_add_hooks(struct lsm_info *info, bool is_mutable) +int __must_check security_add_hooks(struct lsm_info *info, bool is_mutable) { struct security_hook_heads *heads; int i; heads = get_security_hook_heads(is_mutable); if (IS_ERR(heads)) - panic("Failed to get security heads: %ld\n", PTR_ERR(heads)); + return PTR_ERR(heads); + if (!try_module_get(info->owner)) + return -EINVAL; + + if (mutex_lock_killable(&lsm_info_lock)) { + module_put(info->owner); + return -EINTR; + } for (i = 0; i < info->count; i++) security_add_hook(&info->hooks[i], info, heads); - - mutex_lock(&lsm_info_lock); hlist_add_tail_rcu(&info->list, &lsm_info_head); mutex_unlock(&lsm_info_lock); + + return 0; } +EXPORT_SYMBOL_GPL(security_add_hooks); int call_lsm_notifier(enum lsm_event event, void *data) { diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index b324f03ae723..fb830dc80e15 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -7132,7 +7132,7 @@ static __init int selinux_init(void) hashtab_cache_init(); - security_add_hooks(&selinux_info, is_mutable); + BUG_ON(security_add_hooks(&selinux_info, is_mutable)); if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET)) panic("SELinux: Unable to register AVC netcache callback\n"); diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 86fe6467e0fb..0844776c4d18 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -4843,7 +4843,7 @@ static __init int smack_init(void) /* * Register with LSM */ - security_add_hooks(&smack_info, false); + BUG_ON(security_add_hooks(&smack_info, false)); return 0; } diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c index 879d358198b8..4b08021338dc 100644 --- a/security/tomoyo/tomoyo.c +++ b/security/tomoyo/tomoyo.c @@ -545,7 +545,7 @@ static int __init tomoyo_init(void) if (!security_module_enable("tomoyo")) return 0; /* register ourselves with the security framework */ - security_add_hooks(&tomoyo_info, false); + BUG_ON(security_add_hooks(&tomoyo_info, false)); printk(KERN_INFO "TOMOYO Linux initialized\n"); cred->security = &tomoyo_kernel_domain; tomoyo_mm_init(); diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c index 7f2ce8f7c11f..06dd2eb5d0ca 100644 --- a/security/yama/yama_lsm.c +++ b/security/yama/yama_lsm.c @@ -482,6 +482,6 @@ static inline void yama_init_sysctl(void) { } void __init yama_add_hooks(void) { pr_info("Yama: becoming mindful.\n"); - security_add_hooks(&yama_info, false); + BUG_ON(security_add_hooks(&yama_info, false)); yama_init_sysctl(); }