From patchwork Sat Jul 30 20:03:24 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kirill Marinushkin X-Patchwork-Id: 9253235 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 A59ED601C0 for ; Sat, 30 Jul 2016 20:03:33 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 93A6F2842D for ; Sat, 30 Jul 2016 20:03:33 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 836022842F; Sat, 30 Jul 2016 20:03:33 +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=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 015922842D for ; Sat, 30 Jul 2016 20:03:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753315AbcG3UDb (ORCPT ); Sat, 30 Jul 2016 16:03:31 -0400 Received: from mail-wm0-f67.google.com ([74.125.82.67]:34218 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753115AbcG3UDa (ORCPT ); Sat, 30 Jul 2016 16:03:30 -0400 Received: by mail-wm0-f67.google.com with SMTP id q128so20464811wma.1; Sat, 30 Jul 2016 13:03:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=fTwpraVcX9biP9OZDBU2forAuRUVLt653k0VT1A7/cg=; b=Q3b6Ys8K86RLCt/p9kRJW2I9x3L7IBuyMxu8O6f8k+aThFFmvHt8C9oR3EbD652Kub Xcflxym65F2IcJkZZ86lTAD4AtGb0ICD/zbzzMbZlT9zgryqBLreOPBwPP1m1yIYoJwJ B4BtLELO8xYJfpMp4UThBUHgpKmaoM67inXu0RMS+ME6V7TnvlukRWeytSbck4Eb5o/H SX8LtMA99d8g2376BUoYSFB/lS0DKy8hcz1mq14u8++/u6ILFsUkNDNUzCLFsYNcvMLq 8vPn86r9OJOzSLNpiNfHrcLZD0hUXwh0iIOsH6ryHWfU1fukliw3U61Xb2B0DWTDRIP1 R8/Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=fTwpraVcX9biP9OZDBU2forAuRUVLt653k0VT1A7/cg=; b=TFQx2V93jwCx6e3/JCewgxY5DIKYv8t+VaZ8dWlYKGwV9mcwXiV+xNTgmYs7ou+Kcp VEwBcGeA/V4FeLmfvsnnESw3x+o84DBzMR4Hc87xBWf2IUmfGySNZiOTEMci9uy91r69 Xq0u8iL98DsiLWmH7UBkoKB0FdbGZiWQk/+isT9DVIr7EPMlC+gAJOrAY9YRdSLK4Ho+ WAsltus7X6lJxhpDyQ3KZnCvSvqVDAI8fD7VpyU9+K71juQdr1njBBKgFrLo/b+P4nlX iA+EpK5jCfTMm+FfZwcZqzbsRkeYoA/7PQfOcAB1kKM/wCe/bhoEyLLiaLSRxy2vIYVK eaZQ== X-Gm-Message-State: AEkoouvl6WifXiyPbY4fgXSp06i19wyTNXceijrQHDl1quz3+bQOwhku7IinLneJT4bs4Q== X-Received: by 10.28.167.80 with SMTP id q77mr7073714wme.62.1469909008099; Sat, 30 Jul 2016 13:03:28 -0700 (PDT) Received: from kirill-Lenovo-B570e.localdomain (x4dba347c.dyn.telefonica.de. [77.186.52.124]) by smtp.gmail.com with ESMTPSA id x203sm9098117wmg.0.2016.07.30.13.03.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 30 Jul 2016 13:03:27 -0700 (PDT) From: Kirill Marinushkin To: dhowells@redhat.com Cc: zer0mem@yahoo.com, gregkh@linuxfoundation.org, serge@hallyn.com, james.l.morris@oracle.com, keyrings@vger.kernel.org, linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org, k.marinushkin@gmail.com Subject: [PATCH] KEYS: Sort out big_key initialisation Date: Sat, 30 Jul 2016 22:03:24 +0200 Message-Id: <1469909004-28618-1-git-send-email-k.marinushkin@gmail.com> X-Mailer: git-send-email 1.9.1 Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: X-Virus-Scanned: ClamAV using ClamSMTP big_key has two separate initialisation functions, one that registers the key type and one that registers the crypto. If the key type fails to register, there's no problem if the crypto registers successfully because there's no way to reach the crypto except through the key type. However, if the key type registers successfully but the crypto does not, big_key_rng and big_key_blkcipher may end up set to NULL - but the code neither checks for this nor unregisters the big key key type. Furthermore, since the key type is registered before the crypto, it is theoretically possible for the kernel to try adding a big_key before the crypto is set up, leading to the same effect. Fix this by merging big_key_crypto_init() and big_key_init() and calling the resulting function late. If they're going to be encrypted, we shouldn't be creating big_keys before we have the facilities to do the encryption available. The key type registration is also moved after the crypto initialisation. The fix also includes message printing on failure. If the big_key type isn't correctly set up, simply doing: dd if=/dev/zero bs=4096 count=1 | keyctl padd big_key a @s ought to cause an oops. Signed-off-by: David Howells cc: Peter Hlavaty cc: stable@vger.kernel.org Signed-off-by: Kirill Marinushkin --- security/keys/Kconfig | 2 +- security/keys/big_key.c | 62 +++++++++++++++++++++++++++---------------------- 2 files changed, 35 insertions(+), 29 deletions(-) diff --git a/security/keys/Kconfig b/security/keys/Kconfig index f826e87..8213221 100644 --- a/security/keys/Kconfig +++ b/security/keys/Kconfig @@ -44,7 +44,7 @@ config BIG_KEYS select CRYPTO select CRYPTO_AES select CRYPTO_ECB - select CRYPTO_RNG + select CRYPTO_ANSI_CPRNG help This option provides support for holding large keys within the kernel (for example Kerberos ticket caches). The data may be stored out to diff --git a/security/keys/big_key.c b/security/keys/big_key.c index c0b3030..fce1df9 100644 --- a/security/keys/big_key.c +++ b/security/keys/big_key.c @@ -9,6 +9,7 @@ * 2 of the Licence, or (at your option) any later version. */ +#define pr_fmt(fmt) "big_key: "fmt #include #include #include @@ -341,44 +342,49 @@ error: */ static int __init big_key_init(void) { - return register_key_type(&key_type_big_key); -} - -/* - * Initialize big_key crypto and RNG algorithms - */ -static int __init big_key_crypto_init(void) -{ - int ret = -EINVAL; + struct crypto_skcipher *cipher; + struct crypto_rng *rng; + int ret; - /* init RNG */ - big_key_rng = crypto_alloc_rng(big_key_rng_name, 0, 0); - if (IS_ERR(big_key_rng)) { - big_key_rng = NULL; - return -EFAULT; + rng = crypto_alloc_rng(big_key_rng_name, 0, 0); + if (IS_ERR(rng)) { + pr_err("Can't alloc rng: %ld\n", PTR_ERR(rng)); + return PTR_ERR(rng); } + big_key_rng = rng; + /* seed RNG */ - ret = crypto_rng_reset(big_key_rng, NULL, crypto_rng_seedsize(big_key_rng)); - if (ret) - goto error; + ret = crypto_rng_reset(rng, NULL, crypto_rng_seedsize(rng)); + if (ret) { + pr_err("Can't reset rng: %d\n", ret); + goto error_rng; + } - /* init block cipher */ - big_key_skcipher = crypto_alloc_skcipher(big_key_alg_name, - 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(big_key_skcipher)) { - big_key_skcipher = NULL; - ret = -EFAULT; - goto error; + cipher = crypto_alloc_skcipher(big_key_alg_name, + 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(cipher)) { + ret = PTR_ERR(cipher); + pr_err("Can't alloc crypto: %d\n", ret); + goto error_rng; + } + + big_key_skcipher = cipher; + + ret = register_key_type(&key_type_big_key); + if (ret < 0) { + pr_err("Can't register key type: %d\n", ret); + goto error_cipher; } return 0; -error: +error_cipher: + crypto_free_skcipher(big_key_skcipher); +error_rng: crypto_free_rng(big_key_rng); - big_key_rng = NULL; + return ret; } -device_initcall(big_key_init); -late_initcall(big_key_crypto_init); +late_initcall(big_key_init);