From patchwork Wed Oct 23 00:18:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lakshmi Ramasubramanian X-Patchwork-Id: 11205557 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C90961515 for ; Wed, 23 Oct 2019 00:18:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A83EA2086D for ; Wed, 23 Oct 2019 00:18:44 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="nQfxB7Rh" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732256AbfJWASZ (ORCPT ); Tue, 22 Oct 2019 20:18:25 -0400 Received: from linux.microsoft.com ([13.77.154.182]:45252 "EHLO linux.microsoft.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732218AbfJWASZ (ORCPT ); Tue, 22 Oct 2019 20:18:25 -0400 Received: from nramas-ThinkStation-P520.corp.microsoft.com (unknown [131.107.174.108]) by linux.microsoft.com (Postfix) with ESMTPSA id 4E0AA2010AC3; Tue, 22 Oct 2019 17:18:24 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 4E0AA2010AC3 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1571789904; bh=ZxF80hLmpS4odHnXd8DZjntedVTyJ3tH1vjLMOXe8os=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nQfxB7Rh3YN88VbtVbjqd7vP5nGaCHsKqZgVYm3tXgm6uFu/1QF1Ovv9OhP0f3I2B 3HOdT/Yjw3cGFebSmHU3Z17BB34MGPkkotsW/fghalngocZmk/mHAat/sfsasfq1qg W2JfR9lx+ZSRtYHRaRFTv+7GG2IomNjKpwzRHpIA= From: Lakshmi Ramasubramanian To: zohar@linux.ibm.com, dhowells@redhat.com, casey@schaufler-ca.com, sashal@kernel.org, jamorris@linux.microsoft.com, linux-security-module@vger.kernel.org, linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org, keyrings@vger.kernel.org Cc: nramas@linux.microsoft.com Subject: [PATCH v1 1/6] KEYS: Helper function to check if the given keyring is builtin_trusted_keys Date: Tue, 22 Oct 2019 17:18:13 -0700 Message-Id: <20191023001818.3684-2-nramas@linux.microsoft.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191023001818.3684-1-nramas@linux.microsoft.com> References: <20191023001818.3684-1-nramas@linux.microsoft.com> Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: Helper function to check if the given keyring is the builtin_trusted_keys keyring. This function is used by ima to determine if a key is added to the builtin_trusted_keys keyring. Signed-off-by: Lakshmi Ramasubramanian --- certs/system_keyring.c | 5 +++++ include/keys/system_keyring.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/certs/system_keyring.c b/certs/system_keyring.c index 1eba08a1af82..5533c7f92fef 100644 --- a/certs/system_keyring.c +++ b/certs/system_keyring.c @@ -283,3 +283,8 @@ void __init set_platform_trusted_keys(struct key *keyring) platform_trusted_keys = keyring; } #endif + +inline bool is_builtin_trusted_keyring(struct key *keyring) +{ + return (keyring == builtin_trusted_keys); +} diff --git a/include/keys/system_keyring.h b/include/keys/system_keyring.h index c1a96fdf598b..2bc0aaa07f05 100644 --- a/include/keys/system_keyring.h +++ b/include/keys/system_keyring.h @@ -66,4 +66,6 @@ static inline void set_platform_trusted_keys(struct key *keyring) } #endif +extern bool is_builtin_trusted_keyring(struct key *keyring); + #endif /* _KEYS_SYSTEM_KEYRING_H */ From patchwork Wed Oct 23 00:18:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lakshmi Ramasubramanian X-Patchwork-Id: 11205565 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A3C0F1515 for ; Wed, 23 Oct 2019 00:18:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 777272086D for ; Wed, 23 Oct 2019 00:18:52 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="BlBqLSaB" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727309AbfJWASo (ORCPT ); Tue, 22 Oct 2019 20:18:44 -0400 Received: from linux.microsoft.com ([13.77.154.182]:45260 "EHLO linux.microsoft.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732221AbfJWASZ (ORCPT ); Tue, 22 Oct 2019 20:18:25 -0400 Received: from nramas-ThinkStation-P520.corp.microsoft.com (unknown [131.107.174.108]) by linux.microsoft.com (Postfix) with ESMTPSA id 746FA2010AC4; Tue, 22 Oct 2019 17:18:24 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 746FA2010AC4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1571789904; bh=XMnesZyw0QRVpbTGsE9Hc/rqUu5GYJWuVQuZdKM+XUs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BlBqLSaBU2u6bMM8N2CJLmtSSyrj8x+DxdgP4YQcrsfxPrZOnClZCgPZOYF2YcAHc 3ppV4GSQ+xO1NVy1kN7rB4MTn03tNVepQIOL/FALEZqDoaOoHL3eoArCEClDX+gfEL zRe+Ml5aK0gq0sJyT3c3XZGCdwsAMuJmUBdQ2lRY= From: Lakshmi Ramasubramanian To: zohar@linux.ibm.com, dhowells@redhat.com, casey@schaufler-ca.com, sashal@kernel.org, jamorris@linux.microsoft.com, linux-security-module@vger.kernel.org, linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org, keyrings@vger.kernel.org Cc: nramas@linux.microsoft.com Subject: [PATCH v1 2/6] KEYS: ima: Refactored process_buffer_measurement function so that it can measure any buffer (and not just KEXEC_CMDLINE one) Date: Tue, 22 Oct 2019 17:18:14 -0700 Message-Id: <20191023001818.3684-3-nramas@linux.microsoft.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191023001818.3684-1-nramas@linux.microsoft.com> References: <20191023001818.3684-1-nramas@linux.microsoft.com> Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: process_buffer_measurement currently supports measuring kexec command line only. This function has been refactored to support more than kexec_cmdline. With this change this function can be used for measuring any buffer. This function is now also used by ima to measure keys besides used for measuring kexec command line. Signed-off-by: Lakshmi Ramasubramanian --- security/integrity/ima/ima.h | 3 +++ security/integrity/ima/ima_main.c | 29 ++++++++++++++--------------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 011b91c79351..b6847ee1f47a 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -209,6 +209,9 @@ void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file, struct evm_ima_xattr_data *xattr_value, int xattr_len, int pcr, struct ima_template_desc *template_desc); +void process_buffer_measurement(const void *buf, int size, + const char *eventname, int pcr, + struct ima_template_desc *template_desc); void ima_audit_measurement(struct integrity_iint_cache *iint, const unsigned char *filename); int ima_alloc_init_template(struct ima_event_data *event_data, diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 584019728660..8e965d18fb21 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -610,14 +610,14 @@ int ima_load_data(enum kernel_load_data_id id) * @buf: pointer to the buffer that needs to be added to the log. * @size: size of buffer(in bytes). * @eventname: event name to be used for the buffer entry. - * @cred: a pointer to a credentials structure for user validation. - * @secid: the secid of the task to be validated. + * @pcr: pcr to extend the measurement + * @template_desc: template description * * Based on policy, the buffer is measured into the ima log. */ -static void process_buffer_measurement(const void *buf, int size, - const char *eventname, - const struct cred *cred, u32 secid) +void process_buffer_measurement(const void *buf, int size, + const char *eventname, int pcr, + struct ima_template_desc *template_desc) { int ret = 0; struct ima_template_entry *entry = NULL; @@ -626,19 +626,11 @@ static void process_buffer_measurement(const void *buf, int size, .filename = eventname, .buf = buf, .buf_len = size}; - struct ima_template_desc *template_desc = NULL; struct { struct ima_digest_data hdr; char digest[IMA_MAX_DIGEST_SIZE]; } hash = {}; int violation = 0; - int pcr = CONFIG_IMA_MEASURE_PCR_IDX; - int action = 0; - - action = ima_get_action(NULL, cred, secid, 0, KEXEC_CMDLINE, &pcr, - &template_desc); - if (!(action & IMA_MEASURE)) - return; iint.ima_hash = &hash.hdr; iint.ima_hash->algo = ima_hash_algo; @@ -670,12 +662,19 @@ static void process_buffer_measurement(const void *buf, int size, */ void ima_kexec_cmdline(const void *buf, int size) { + int pcr = CONFIG_IMA_MEASURE_PCR_IDX; + struct ima_template_desc *template_desc = ima_template_desc_current(); + int action; u32 secid; if (buf && size != 0) { security_task_getsecid(current, &secid); - process_buffer_measurement(buf, size, "kexec-cmdline", - current_cred(), secid); + action = ima_get_action(NULL, current_cred(), secid, 0, + KEXEC_CMDLINE, &pcr, &template_desc); + if (!(action & IMA_MEASURE)) + return; + process_buffer_measurement(buf, size, "kexec-cmdline", pcr, + template_desc); } } From patchwork Wed Oct 23 00:18:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lakshmi Ramasubramanian X-Patchwork-Id: 11205561 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3F0FD13B1 for ; Wed, 23 Oct 2019 00:18:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 1E0912086D for ; Wed, 23 Oct 2019 00:18:52 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="GR5qiulu" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732686AbfJWASo (ORCPT ); Tue, 22 Oct 2019 20:18:44 -0400 Received: from linux.microsoft.com ([13.77.154.182]:45276 "EHLO linux.microsoft.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732224AbfJWASZ (ORCPT ); Tue, 22 Oct 2019 20:18:25 -0400 Received: from nramas-ThinkStation-P520.corp.microsoft.com (unknown [131.107.174.108]) by linux.microsoft.com (Postfix) with ESMTPSA id 9ADA92010AC5; Tue, 22 Oct 2019 17:18:24 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 9ADA92010AC5 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1571789904; bh=4Bq0D88j9WL7mEGpp0j6poBpUK+duhRJiZbGEgFGP/8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GR5qiulus8Ap/Lz+o/JQtHylY8rYL6Hwe4J3vcj3qCPdx3Eu/MnySgUf1STSslCmk +/0JcClLmQ/+57UJM7TQNqXeR37TjqwF8YcPnoUAbOVWZRTDonJFsrmllMChXvybFd 4DHp635ZK1QIAmcdvWji6U3kF9rPLiBm32MA9YAE= From: Lakshmi Ramasubramanian To: zohar@linux.ibm.com, dhowells@redhat.com, casey@schaufler-ca.com, sashal@kernel.org, jamorris@linux.microsoft.com, linux-security-module@vger.kernel.org, linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org, keyrings@vger.kernel.org Cc: nramas@linux.microsoft.com Subject: [PATCH v1 3/6] KEYS: ima hook to measure builtin_trusted_keys Date: Tue, 22 Oct 2019 17:18:15 -0700 Message-Id: <20191023001818.3684-4-nramas@linux.microsoft.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191023001818.3684-1-nramas@linux.microsoft.com> References: <20191023001818.3684-1-nramas@linux.microsoft.com> Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: Add a new ima hook to measure keys added to builtin_trusted_keys keyring. Updated ima_match_rules function to handle the new ima hook. This is used to determine if ima policy requires measurement of keys added to builtin_trusted_keys keyring. Signed-off-by: Lakshmi Ramasubramanian --- Documentation/ABI/testing/ima_policy | 1 + security/integrity/ima/ima.h | 1 + security/integrity/ima/ima_api.c | 1 + security/integrity/ima/ima_policy.c | 5 ++++- 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Documentation/ABI/testing/ima_policy b/Documentation/ABI/testing/ima_policy index fc376a323908..25566c74e679 100644 --- a/Documentation/ABI/testing/ima_policy +++ b/Documentation/ABI/testing/ima_policy @@ -29,6 +29,7 @@ Description: [FIRMWARE_CHECK] [KEXEC_KERNEL_CHECK] [KEXEC_INITRAMFS_CHECK] [KEXEC_CMDLINE] + [BUILTIN_TRUSTED_KEYS] mask:= [[^]MAY_READ] [[^]MAY_WRITE] [[^]MAY_APPEND] [[^]MAY_EXEC] fsmagic:= hex value diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index b6847ee1f47a..0d2908036882 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -189,6 +189,7 @@ static inline unsigned long ima_hash_key(u8 *digest) hook(KEXEC_INITRAMFS_CHECK) \ hook(POLICY_CHECK) \ hook(KEXEC_CMDLINE) \ + hook(BUILTIN_TRUSTED_KEYS) \ hook(MAX_CHECK) #define __ima_hook_enumify(ENUM) ENUM, diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index f614e22bf39f..cc04706b7e7a 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c @@ -175,6 +175,7 @@ void ima_add_violation(struct file *file, const unsigned char *filename, * subj,obj, and type: are LSM specific. * func: FILE_CHECK | BPRM_CHECK | CREDS_CHECK | MMAP_CHECK | MODULE_CHECK * | KEXEC_CMDLINE + * | BUILTIN_TRUSTED_KEYS * mask: contains the permission mask * fsmagic: hex value * diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index 6df7f641ff66..944636076152 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c @@ -370,7 +370,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, { int i; - if (func == KEXEC_CMDLINE) { + if ((func == KEXEC_CMDLINE) || (func == BUILTIN_TRUSTED_KEYS)) { if ((rule->flags & IMA_FUNC) && (rule->func == func)) return true; return false; @@ -959,6 +959,9 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) entry->func = POLICY_CHECK; else if (strcmp(args[0].from, "KEXEC_CMDLINE") == 0) entry->func = KEXEC_CMDLINE; + else if (strcmp(args[0].from, + "BUILTIN_TRUSTED_KEYS") == 0) + entry->func = BUILTIN_TRUSTED_KEYS; else result = -EINVAL; if (!result) From patchwork Wed Oct 23 00:18:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lakshmi Ramasubramanian X-Patchwork-Id: 11205543 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 123B81515 for ; Wed, 23 Oct 2019 00:18:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E5EA1218AE for ; Wed, 23 Oct 2019 00:18:26 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="fCvq9SD+" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732367AbfJWAS0 (ORCPT ); Tue, 22 Oct 2019 20:18:26 -0400 Received: from linux.microsoft.com ([13.77.154.182]:45286 "EHLO linux.microsoft.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732229AbfJWASZ (ORCPT ); Tue, 22 Oct 2019 20:18:25 -0400 Received: from nramas-ThinkStation-P520.corp.microsoft.com (unknown [131.107.174.108]) by linux.microsoft.com (Postfix) with ESMTPSA id C1AEE2010AC6; Tue, 22 Oct 2019 17:18:24 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com C1AEE2010AC6 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1571789904; bh=3EEDwTWXlit7lCdzWaSZuvopxoV1OJ3w7wj1bKW7mGw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fCvq9SD+Gw3CmY/a9mWTsF8csnkUdjg9+cJSNEbSLuHnfd2f0J+x1CSzcSQtQchdX LvwX4jJDS8W19f6E0yq8crBIim2Jo27zlfzJaGloQGtvBjP3Bm2an1wOHpWfnO5xdB ymFlHTDtuCS56mtCOSoQDpwqGxr7EGonKHTXvPJk= From: Lakshmi Ramasubramanian To: zohar@linux.ibm.com, dhowells@redhat.com, casey@schaufler-ca.com, sashal@kernel.org, jamorris@linux.microsoft.com, linux-security-module@vger.kernel.org, linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org, keyrings@vger.kernel.org Cc: nramas@linux.microsoft.com Subject: [PATCH v1 4/6] KEYS: ima functions to queue and dequeue keys to measure Date: Tue, 22 Oct 2019 17:18:16 -0700 Message-Id: <20191023001818.3684-5-nramas@linux.microsoft.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191023001818.3684-1-nramas@linux.microsoft.com> References: <20191023001818.3684-1-nramas@linux.microsoft.com> Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: Implement functions to queue a key for measurement if ima is not yet initialized. And, when ima initialization is complete, process any queued key measurement requests. This change set implements the functions to queue and de-queue requests. The change to actually measure the keys is in another patch. Signed-off-by: Lakshmi Ramasubramanian --- security/integrity/ima/ima.h | 15 ++++ security/integrity/ima/ima_init.c | 11 ++- security/integrity/ima/ima_queue.c | 128 +++++++++++++++++++++++++++++ 3 files changed, 153 insertions(+), 1 deletion(-) diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 0d2908036882..7e4d4169798d 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -21,6 +21,7 @@ #include #include #include +#include #include "../integrity.h" @@ -52,6 +53,7 @@ extern int ima_policy_flag; extern int ima_hash_algo; extern int ima_appraise; extern struct tpm_chip *ima_tpm_chip; +extern bool ima_initialized; /* IMA event related data */ struct ima_event_data { @@ -158,6 +160,8 @@ void ima_init_template_list(void); int __init ima_init_digests(void); int ima_lsm_policy_change(struct notifier_block *nb, unsigned long event, void *lsm_data); +int ima_measure_key(struct key *keyring, struct key *key); +void ima_measure_queued_trusted_keys(void); /* * used to protect h_table and sha_table @@ -197,6 +201,17 @@ enum ima_hooks { __ima_hooks(__ima_hook_enumify) }; +/* + * To track trusted keys that need to be measured when IMA is initialized. + */ +struct ima_trusted_key_entry { + struct list_head list; + void *public_key; + u32 public_key_len; + char *key_description; + enum ima_hooks func; +}; + /* LIM API function definitions */ int ima_get_action(struct inode *inode, const struct cred *cred, u32 secid, int mask, enum ima_hooks func, int *pcr, diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c index 5d55ade5f3b9..32b9147fe410 100644 --- a/security/integrity/ima/ima_init.c +++ b/security/integrity/ima/ima_init.c @@ -23,6 +23,7 @@ /* name for boot aggregate entry */ static const char boot_aggregate_name[] = "boot_aggregate"; struct tpm_chip *ima_tpm_chip; +bool ima_initialized; /* Add the boot aggregate to the IMA measurement list and extend * the PCR register. @@ -131,5 +132,13 @@ int __init ima_init(void) ima_init_policy(); - return ima_fs_init(); + rc = ima_fs_init(); + if (rc != 0) + return rc; + + ima_initialized = true; + + ima_measure_queued_trusted_keys(); + + return 0; } diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c index 1ce8b1701566..a262e289615b 100644 --- a/security/integrity/ima/ima_queue.c +++ b/security/integrity/ima/ima_queue.c @@ -19,6 +19,8 @@ #include #include +#include +#include #include "ima.h" #define AUDIT_CAUSE_LEN_MAX 32 @@ -46,6 +48,13 @@ struct ima_h_table ima_htable = { */ static DEFINE_MUTEX(ima_extend_list_mutex); +/* + * Used to synchronize access to the list of trusted keys (ima_trusted_keys) + * that need to be measured when IMA is initialized. + */ +static DEFINE_MUTEX(ima_trusted_keys_mutex); +static LIST_HEAD(ima_trusted_keys); + /* lookup up the digest value in the hash table, and return the entry */ static struct ima_queue_entry *ima_lookup_digest_entry(u8 *digest_value, int pcr) @@ -232,3 +241,122 @@ int __init ima_init_digests(void) return 0; } + +/* + * Maps the given keyring to a IMA Hook. + * @keyring: A keyring to which a key maybe linked to. + * + * This function currently handles only builtin_trusted_keys. + * To handle more keyrings, this function, ima hook and + * ima policy handler need to be updated. + */ +static enum ima_hooks keyring_policy_map(struct key *keyring) +{ + enum ima_hooks func = NONE; + + if (is_builtin_trusted_keyring(keyring)) + func = BUILTIN_TRUSTED_KEYS; + + return func; +} + +static void ima_free_trusted_key_entry(struct ima_trusted_key_entry *entry) +{ + if (entry != NULL) { + if (entry->public_key != NULL) + kzfree(entry->public_key); + if (entry->key_description != NULL) + kzfree(entry->key_description); + kzfree(entry); + } +} + +static struct ima_trusted_key_entry *ima_alloc_trusted_queue_entry( + struct key *key, + enum ima_hooks func) +{ + int rc = 0; + const struct public_key *pk; + size_t key_description_len; + struct ima_trusted_key_entry *entry = NULL; + + pk = key->payload.data[asym_crypto]; + key_description_len = strlen(key->description) + 1; + entry = kzalloc(sizeof(*entry), GFP_KERNEL); + if (entry != NULL) { + entry->public_key = kzalloc(pk->keylen, GFP_KERNEL); + entry->key_description = + kzalloc(key_description_len, GFP_KERNEL); + } + + if ((entry == NULL) || (entry->public_key == NULL) || + (entry->key_description == NULL)) { + rc = -ENOMEM; + goto out; + } + + strcpy(entry->key_description, key->description); + memcpy(entry->public_key, pk->key, pk->keylen); + entry->public_key_len = pk->keylen; + entry->func = func; + rc = 0; + +out: + if (rc) { + ima_free_trusted_key_entry(entry); + entry = NULL; + } + + return entry; +} + +/* + * ima_measure_key + * @keyring the keyring to which the key is linked to. + * @key the key being created or updated + * Measure keys created or updated in the system + * + * On success return 0. + * Return appropriate error code on error + */ +int ima_measure_key(struct key *keyring, struct key *key) +{ + int rc = 0; + struct ima_trusted_key_entry *entry = NULL; + enum ima_hooks func; + bool queued = false; + + func = keyring_policy_map(keyring); + if (func == NONE) + return 0; + + mutex_lock(&ima_trusted_keys_mutex); + + if (!ima_initialized) { + entry = ima_alloc_trusted_queue_entry(key, func); + if (entry != NULL) { + INIT_LIST_HEAD(&entry->list); + list_add_tail(&entry->list, &ima_trusted_keys); + queued = true; + } else + rc = -ENOMEM; + } + + mutex_unlock(&ima_trusted_keys_mutex); + + return rc; +} + +void ima_measure_queued_trusted_keys(void) +{ + struct ima_trusted_key_entry *entry, *tmp; + + mutex_lock(&ima_trusted_keys_mutex); + + list_for_each_entry_safe(entry, tmp, &ima_trusted_keys, list) { + list_del(&entry->list); + ima_free_trusted_key_entry(entry); + } + + mutex_unlock(&ima_trusted_keys_mutex); +} From patchwork Wed Oct 23 00:18:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lakshmi Ramasubramanian X-Patchwork-Id: 11205541 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D9E7B13B1 for ; Wed, 23 Oct 2019 00:18:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B87C82184C for ; Wed, 23 Oct 2019 00:18:26 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="e3oF84ac" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732218AbfJWAS0 (ORCPT ); Tue, 22 Oct 2019 20:18:26 -0400 Received: from linux.microsoft.com ([13.77.154.182]:45294 "EHLO linux.microsoft.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732286AbfJWASZ (ORCPT ); Tue, 22 Oct 2019 20:18:25 -0400 Received: from nramas-ThinkStation-P520.corp.microsoft.com (unknown [131.107.174.108]) by linux.microsoft.com (Postfix) with ESMTPSA id E95142010AC7; Tue, 22 Oct 2019 17:18:24 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com E95142010AC7 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1571789905; bh=IPbDEriMVz33Apnnpw3koY2My/6+Zihb+a8aOw3IrZM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=e3oF84acreEnePlHEqDJz62oy6fZyLD4xGnTB9Kp+hhfWDIQG7EBSjmicaJBnrDlE /ZSZ/5EL9gUynNlVWtvagcompoOYknFdgjZnKGMFFdex4yv7hboYbuzirYE58Nlkjh 5Gql6mmNWYmgUvHvwnTRo0xv58d0W9bkaJZy0niY= From: Lakshmi Ramasubramanian To: zohar@linux.ibm.com, dhowells@redhat.com, casey@schaufler-ca.com, sashal@kernel.org, jamorris@linux.microsoft.com, linux-security-module@vger.kernel.org, linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org, keyrings@vger.kernel.org Cc: nramas@linux.microsoft.com Subject: [PATCH v1 5/6] KEYS: measure queued keys Date: Tue, 22 Oct 2019 17:18:17 -0700 Message-Id: <20191023001818.3684-6-nramas@linux.microsoft.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191023001818.3684-1-nramas@linux.microsoft.com> References: <20191023001818.3684-1-nramas@linux.microsoft.com> Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: Call process_buffer_measurement to measure keys that are added and updated in the system. Signed-off-by: Lakshmi Ramasubramanian --- security/integrity/ima/ima_main.c | 23 +++++++++++++++++++++ security/integrity/ima/ima_queue.c | 32 ++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 8e965d18fb21..7c2afb954f19 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -678,6 +678,29 @@ void ima_kexec_cmdline(const void *buf, int size) } } +/* + * ima_post_key_create_or_update + * @keyring points to the keyring to which the key belongs + * @key points to the key being created or updated + * @cred cred structure + * @flags flags passed to key_create_or_update function + * @create flag to indicate whether the key was created or updated + * + * IMA hook called when a new key is created or updated. + * + * On success return 0. + * Return appropriate error code on error + */ +int ima_post_key_create_or_update(struct key *keyring, struct key *key, + const struct cred *cred, + unsigned long flags, bool create) +{ + if (key->type != &key_type_asymmetric) + return 0; + + return ima_measure_key(keyring, key); +} + static int __init init_ima(void) { int error; diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c index a262e289615b..0da11a292f99 100644 --- a/security/integrity/ima/ima_queue.c +++ b/security/integrity/ima/ima_queue.c @@ -322,7 +322,12 @@ static struct ima_trusted_key_entry *ima_alloc_trusted_queue_entry( int ima_measure_key(struct key *keyring, struct key *key) { int rc = 0; + int pcr = CONFIG_IMA_MEASURE_PCR_IDX; + struct ima_template_desc *template_desc = ima_template_desc_current(); + int action; struct ima_trusted_key_entry *entry = NULL; + const struct public_key *pk; + u32 secid; enum ima_hooks func; bool queued = false; @@ -344,16 +349,43 @@ int ima_measure_key(struct key *keyring, struct key *key) mutex_unlock(&ima_trusted_keys_mutex); + if ((rc == 0) && !queued) { + security_task_getsecid(current, &secid); + action = ima_get_action(NULL, current_cred(), secid, 0, + func, &pcr, &template_desc); + if (action & IMA_MEASURE) { + pk = key->payload.data[asym_crypto]; + process_buffer_measurement(pk->key, pk->keylen, + key->description, + pcr, template_desc); + } + } + return rc; } void ima_measure_queued_trusted_keys(void) { struct ima_trusted_key_entry *entry, *tmp; + int pcr = CONFIG_IMA_MEASURE_PCR_IDX; + struct ima_template_desc *template_desc = ima_template_desc_current(); + int action; + u32 secid; mutex_lock(&ima_trusted_keys_mutex); list_for_each_entry_safe(entry, tmp, &ima_trusted_keys, list) { + security_task_getsecid(current, &secid); + action = ima_get_action(NULL, current_cred(), secid, 0, + entry->func, &pcr, + &template_desc); + if (action & IMA_MEASURE) { + process_buffer_measurement(entry->public_key, + entry->public_key_len, + entry->key_description, + pcr, + template_desc); + } list_del(&entry->list); ima_free_trusted_key_entry(entry); } From patchwork Wed Oct 23 00:18:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lakshmi Ramasubramanian X-Patchwork-Id: 11205553 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1D2C113BD for ; Wed, 23 Oct 2019 00:18:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E73DB2086D for ; Wed, 23 Oct 2019 00:18:37 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="WFw4V83F" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732625AbfJWASh (ORCPT ); Tue, 22 Oct 2019 20:18:37 -0400 Received: from linux.microsoft.com ([13.77.154.182]:45298 "EHLO linux.microsoft.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732315AbfJWAS0 (ORCPT ); Tue, 22 Oct 2019 20:18:26 -0400 Received: from nramas-ThinkStation-P520.corp.microsoft.com (unknown [131.107.174.108]) by linux.microsoft.com (Postfix) with ESMTPSA id 1B7132010AC8; Tue, 22 Oct 2019 17:18:25 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 1B7132010AC8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1571789905; bh=l3/xpxDJDNPHhTjWJ68OgeQThxUX96N97fTeydZwHaM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WFw4V83FIRb9/kKNS80AHaLOAxb18GAxUAoHQDsmgtjgeYqh4zjQTx/5eHQBz4A7W sg6wHJlSkrhtKDNqK5vSXxOCCWZiJYGcF3MRPLdr7YJmMvV9VOlZyVAtHySJPZsNT8 59WqKDVFBJd8zSoyI1OXfNViIfpKYIPGQcm2ymUY= From: Lakshmi Ramasubramanian To: zohar@linux.ibm.com, dhowells@redhat.com, casey@schaufler-ca.com, sashal@kernel.org, jamorris@linux.microsoft.com, linux-security-module@vger.kernel.org, linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org, keyrings@vger.kernel.org Cc: nramas@linux.microsoft.com Subject: [PATCH v1 6/6] KEYS: measure keys when they are created or updated Date: Tue, 22 Oct 2019 17:18:18 -0700 Message-Id: <20191023001818.3684-7-nramas@linux.microsoft.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191023001818.3684-1-nramas@linux.microsoft.com> References: <20191023001818.3684-1-nramas@linux.microsoft.com> Sender: owner-linux-security-module@vger.kernel.org Precedence: bulk List-ID: A new LSM function namely, security_key_create_or_update, has been added. This function is called by key_create_or_update function when a new key is created or an existing key is updated. This call is made when the key has been instantiated and linked to the target keyring. security_key_create_or_update is passed the target keyring, key, key creation flags, and a boolean flag indicating whether the key was newly created or an existing key was updated. This function calls the ima function ima_post_key_create_or_update to measure the key. Signed-off-by: Lakshmi Ramasubramanian --- include/linux/ima.h | 15 +++++++- include/linux/security.h | 13 ++++++- security/keys/key.c | 78 +++++++++++++++++++++++++++++++++++----- security/security.c | 10 ++++++ 4 files changed, 105 insertions(+), 11 deletions(-) diff --git a/include/linux/ima.h b/include/linux/ima.h index a20ad398d260..ce763901380d 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h @@ -24,7 +24,11 @@ extern int ima_post_read_file(struct file *file, void *buf, loff_t size, enum kernel_read_file_id id); extern void ima_post_path_mknod(struct dentry *dentry); extern void ima_kexec_cmdline(const void *buf, int size); - +extern int ima_post_key_create_or_update(struct key *keyring, + struct key *key, + const struct cred *cred, + unsigned long flags, + bool create); #ifdef CONFIG_IMA_KEXEC extern void ima_add_kexec_buffer(struct kimage *image); #endif @@ -91,6 +95,15 @@ static inline void ima_post_path_mknod(struct dentry *dentry) } static inline void ima_kexec_cmdline(const void *buf, int size) {} + +static inline int ima_post_key_create_or_update(struct key *keyring, + struct key *key, + const struct cred *cred, + unsigned long flags, + bool create) +{ + return 0; +} #endif /* CONFIG_IMA */ #ifndef CONFIG_IMA_KEXEC diff --git a/include/linux/security.h b/include/linux/security.h index 5f7441abbf42..c8348da3db2e 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1677,7 +1677,9 @@ void security_key_free(struct key *key); int security_key_permission(key_ref_t key_ref, const struct cred *cred, unsigned perm); int security_key_getsecurity(struct key *key, char **_buffer); - +int security_key_create_or_update(struct key *keyring, struct key *key, + const struct cred *cred, + unsigned long flags, bool create); #else static inline int security_key_alloc(struct key *key, @@ -1704,6 +1706,15 @@ static inline int security_key_getsecurity(struct key *key, char **_buffer) return 0; } +static inline int security_key_create_or_update(struct key *keyring, + struct key *key, + const struct cred *cred, + unsigned long flags, + bool create) +{ + return 0; +} + #endif #endif /* CONFIG_KEYS */ diff --git a/security/keys/key.c b/security/keys/key.c index 764f4c57913e..b913feaf196e 100644 --- a/security/keys/key.c +++ b/security/keys/key.c @@ -781,7 +781,7 @@ static inline key_ref_t __key_update(key_ref_t key_ref, } /** - * key_create_or_update - Update or create and instantiate a key. + * __key_create_or_update - Update or create and instantiate a key. * @keyring_ref: A pointer to the destination keyring with possession flag. * @type: The type of key. * @description: The searchable description for the key. @@ -789,6 +789,8 @@ static inline key_ref_t __key_update(key_ref_t key_ref, * @plen: The length of @payload. * @perm: The permissions mask for a new key. * @flags: The quota flags for a new key. + * @create: Set to true if the key was newly created. + * Set to false if the key was updated. * * Search the destination keyring for a key of the same description and if one * is found, update it, otherwise create and instantiate a new one and create a @@ -805,13 +807,14 @@ static inline key_ref_t __key_update(key_ref_t key_ref, * On success, the possession flag from the keyring ref will be tacked on to * the key ref before it is returned. */ -key_ref_t key_create_or_update(key_ref_t keyring_ref, - const char *type, - const char *description, - const void *payload, - size_t plen, - key_perm_t perm, - unsigned long flags) +static key_ref_t __key_create_or_update(key_ref_t keyring_ref, + const char *type, + const char *description, + const void *payload, + size_t plen, + key_perm_t perm, + unsigned long flags, + bool *create) { struct keyring_index_key index_key = { .description = description, @@ -936,6 +939,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, goto error_link_end; } + *create = true; key_ref = make_key_ref(key, is_key_possessed(keyring_ref)); error_link_end: @@ -948,7 +952,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, error: return key_ref; - found_matching_key: +found_matching_key: /* we found a matching key, so we're going to try to update it * - we can drop the locks first as we have the key pinned */ @@ -964,9 +968,65 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, } } + *create = false; key_ref = __key_update(key_ref, &prep); goto error_free_prep; } + +/** + * key_create_or_update - Update or create and instantiate a key. + * @keyring_ref: A pointer to the destination keyring with possession flag. + * @type: The type of key. + * @description: The searchable description for the key. + * @payload: The data to use to instantiate or update the key. + * @plen: The length of @payload. + * @perm: The permissions mask for a new key. + * @flags: The quota flags for a new key. + * + * Calls the internal function __key_create_or_update. + * If successful calls the security LSM hook. + */ +key_ref_t key_create_or_update(key_ref_t keyring_ref, + const char *type, + const char *description, + const void *payload, + size_t plen, + key_perm_t perm, + unsigned long flags) +{ + key_ref_t key_ref; + struct key *keyring, *key = NULL; + int ret = 0; + bool create = false; + + key_ref = __key_create_or_update(keyring_ref, type, description, + payload, plen, perm, flags, + &create); + if (IS_ERR(key_ref)) + goto out; + + keyring = key_ref_to_ptr(keyring_ref); + key = key_ref_to_ptr(key_ref); + + /* let the security module know about + * the created or updated key. + */ + ret = security_key_create_or_update(keyring, key, + current_cred(), + flags, create); + if (ret < 0) + goto security_error; + else + goto out; + +security_error: + key_unlink(keyring, key); + key_put(key); + key_ref = ERR_PTR(ret); + +out: + return key_ref; +} EXPORT_SYMBOL(key_create_or_update); /** diff --git a/security/security.c b/security/security.c index 250ee2d76406..707a9e7fa94d 100644 --- a/security/security.c +++ b/security/security.c @@ -2303,6 +2303,16 @@ int security_key_getsecurity(struct key *key, char **_buffer) return call_int_hook(key_getsecurity, 0, key, _buffer); } +int security_key_create_or_update(struct key *keyring, + struct key *key, + const struct cred *cred, + unsigned long flags, + bool create) +{ + return ima_post_key_create_or_update(keyring, key, cred, + flags, create); +} + #endif /* CONFIG_KEYS */ #ifdef CONFIG_AUDIT