From patchwork Fri Sep 8 12:14:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Denis Glazkov X-Patchwork-Id: 13377415 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 34922EE7FE3 for ; Fri, 8 Sep 2023 12:14:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231624AbjIHMOg (ORCPT ); Fri, 8 Sep 2023 08:14:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34408 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229713AbjIHMOg (ORCPT ); Fri, 8 Sep 2023 08:14:36 -0400 Received: from mx01.omp.ru (mx01.omp.ru [90.154.21.10]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5EB921BC5; Fri, 8 Sep 2023 05:14:31 -0700 (PDT) Received: from msexch01.omp.ru (10.188.4.12) by msexch02.omp.ru (10.188.4.13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384) id 15.2.986.14; Fri, 8 Sep 2023 15:14:25 +0300 Received: from msexch01.omp.ru ([fe80::4020:d881:621a:6b6b]) by msexch01.omp.ru ([fe80::4020:d881:621a:6b6b%5]) with mapi id 15.02.0986.014; Fri, 8 Sep 2023 15:14:25 +0300 From: Denis Glazkov To: Sergey Shtylyov CC: Denis Glazkov , "dhowells@redhat.com" , "dwmw2@infradead.org" , "keyrings@vger.kernel.org" , "linux-kernel@vger.kernel.org" Subject: [PATCH v2] certs: Add option to disallow non-CA certificates in secondary trusted keying Thread-Topic: [PATCH v2] certs: Add option to disallow non-CA certificates in secondary trusted keying Thread-Index: AQHZ4k4BzqaMvMEYP0mVw3ughXalxQ== Date: Fri, 8 Sep 2023 12:14:25 +0000 Message-ID: <20230908121330.4076-1-d.glazkov@omp.ru> References: In-Reply-To: Accept-Language: ru-RU, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.188.4.40] x-kse-serverinfo: msexch02.omp.ru, 9 x-kse-attachmentfiltering-interceptor-info: protection disabled x-kse-antivirus-interceptor-info: scan successful x-kse-antivirus-info: Clean, bases: 7/15/2023 3:35:00 AM x-kse-bulkmessagesfiltering-scan-result: sender external Content-ID: <3039DAFBA7E16F4FBD26143DC4E2FCD5@omp.ru> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: keyrings@vger.kernel.org The Linux kernel has an IMA (Integrity Measurement Architecture) subsystem to check the integrity of the file system based on digital signatures. IMA uses certificates in `.ima` keying to check integrity. Only certificates issued by one of the trusted CA (Certificate Authority) certificates can be added to the `.ima` keying. The Linux kernel now has a secondary trusted keying to which trusted certificates from user space can be added if you have superuser privileges. Previously, all trusted certificates were in the built-in trusted keying, which could not be modified from user space. Trusted certificates were placed in the built-in trusted keying at kernel compile time. The secondary trusted keying is designed so that any certificates that are signed by one of the trusted CA certificates in the built-in or secondary trusted keyring can be added to it. Let's imagine that we have the following certificate trust chain: ┌───────────────────────────┬─────────────────────┐ │ │ ┌───────┐ │ │ │ │ │ │ ┌────────────▼────────┐ ┌─────────────▼─────▼────┐ │ ┌─────┴─────┐ │.builtin_trusted_keys│◄───┤.secondary_trusted_keys ├──┘ │ .ima │ ├─────────────────────┤ ├────────────────────────┤ ├───────────┤ │ Root CA Cert │-----► Intermediate CA Cert │-----► IMA Cert │ └─────────────────────┘ └────────────────────────┘ └───────────┘ Issues Restricted by -------------► ──────────────► Since the IMA certificate is signed by a CA certificate from a secondary trusted keying, an attacker with superuser privileges will be able to add the IMA certificate to the secondary trusted keying. That is, the IMA certificate will become trusted. Since, with `CONFIG_MODULE_SIG` option enabled, modules can only be loaded into kernel space if they are signed with one of the trusted certificates, an attacker could sign untrusted kernel modules with the private key corresponding to the IMA certificate and successfully load the untrusted modules into kernel space. This patch adds the configuration that once enabled, only certificates that meet the following requirements can be added to the secondary trusted keying: 1. The certificate is a CA (Certificate Authority) 2. The certificate must be used for verifying a CA's signatures 3. The certificate must not be used for digital signatures Signed-off-by: Denis Glazkov --- v1 -> v2: - Rebase the patch from `linux-next` to the main `linux` repo master branch - Make the commit message more detailed - Move the variable declaration to the `if` block - Replace `#ifdef` with `IS_ENABLED` macro --- certs/Kconfig | 9 +++++++++ certs/system_keyring.c | 16 ++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/certs/Kconfig b/certs/Kconfig index 1f109b070877..4a4dc8aab892 100644 --- a/certs/Kconfig +++ b/certs/Kconfig @@ -90,6 +90,15 @@ config SECONDARY_TRUSTED_KEYRING those keys are not blacklisted and are vouched for by a key built into the kernel or already in the secondary trusted keyring. +config SECONDARY_TRUSTED_KEYRING_FOR_CA_CERTIFICATES_ONLY + bool "Allow only CA certificates to be added to the secondary trusted keyring" + depends on SECONDARY_TRUSTED_KEYRING + help + If set, only CA certificates can be added to the secondary trusted keyring. + An acceptable CA certificate must include the `keyCertSign` value in + the `keyUsage` field. CA certificates that include the `digitalSignature` + value in the `keyUsage` field will not be accepted. + config SYSTEM_BLACKLIST_KEYRING bool "Provide system-wide ring of blacklisted keys" depends on KEYS diff --git a/certs/system_keyring.c b/certs/system_keyring.c index 9de610bf1f4b..ee14447374e7 100644 --- a/certs/system_keyring.c +++ b/certs/system_keyring.c @@ -99,6 +99,22 @@ int restrict_link_by_builtin_and_secondary_trusted( /* Allow the builtin keyring to be added to the secondary */ return 0; + if (IS_ENABLED(CONFIG_SECONDARY_TRUSTED_KEYRING_FOR_CA_CERTIFICATES_ONLY) && + dest_keyring == secondary_trusted_keys) { + const struct public_key *pub = payload->data[asym_crypto]; + + if (type != &key_type_asymmetric) + return -EOPNOTSUPP; + if (!pub) + return -ENOPKG; + if (!test_bit(KEY_EFLAG_CA, &pub->key_eflags)) + return -EPERM; + if (!test_bit(KEY_EFLAG_KEYCERTSIGN, &pub->key_eflags)) + return -EPERM; + if (test_bit(KEY_EFLAG_DIGITALSIG, &pub->key_eflags)) + return -EPERM; + } + return restrict_link_by_signature(dest_keyring, type, payload, secondary_trusted_keys); }