From patchwork Mon Jul 3 21:57:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 13300498 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 7FECAEB64DD for ; Mon, 3 Jul 2023 21:57:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231411AbjGCV5U (ORCPT ); Mon, 3 Jul 2023 17:57:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60942 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230206AbjGCV5T (ORCPT ); Mon, 3 Jul 2023 17:57:19 -0400 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 6CB9619F for ; Mon, 3 Jul 2023 14:57:18 -0700 (PDT) Received: from tushar-HP-Pavilion-Laptop-15-eg0xxx.lan (c-98-237-170-177.hsd1.wa.comcast.net [98.237.170.177]) by linux.microsoft.com (Postfix) with ESMTPSA id BB30520AECBD; Mon, 3 Jul 2023 14:57:17 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com BB30520AECBD DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1688421437; bh=eQiDdiGszFkOMDk1+HM/N9CWYJ7B5kMdxIp/HrxE+hU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HkEH6GqHefQ3IMcFxi9qEcIzWzVymw0R8WlJWcRaLzDQrMAjoC4b12i7FO/gs3Nzr tza0yGt9YBhhvrbxELq/kXt4VgnxfcI8HX3H1pLpDPSoBRClFRIMtpfgOgv9Xywlh0 rTaUj84l6vax9yjdp1eGP5a8jYR2XwaWm7FworH8= From: Tushar Sugandhi To: zohar@linux.ibm.com, noodles@fb.com, bauermann@kolabnow.com, kexec@lists.infradead.org, linux-integrity@vger.kernel.org Cc: code@tyhicks.com, nramas@linux.microsoft.com, paul@paul-moore.com Subject: [PATCH 01/10] ima: implement function to allocate buffer at kexec load Date: Mon, 3 Jul 2023 14:57:00 -0700 Message-Id: <20230703215709.1195644-2-tusharsu@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230703215709.1195644-1-tusharsu@linux.microsoft.com> References: <20230703215709.1195644-1-tusharsu@linux.microsoft.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org IMA does not provide a mechanism to allocate memory for IMA log storage during kexec operation. The function should handle the scenario where the kexec load is called multiple times. Implement a function to allocate buffer of size kexec_segment_size at kexec load. If the buffer was already allocated, free that buffer and reallocate. Finally, initialize ima_khdr struct. The patch operates under the assumption that the segment size does not change between kexec load and execute. Signed-off-by: Tushar Sugandhi --- security/integrity/ima/ima_kexec.c | 47 ++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c index 419dc405c831..48a683874044 100644 --- a/security/integrity/ima/ima_kexec.c +++ b/security/integrity/ima/ima_kexec.c @@ -15,6 +15,53 @@ #include "ima.h" #ifdef CONFIG_IMA_KEXEC +struct seq_file ima_kexec_file; +struct ima_kexec_hdr ima_khdr; +static size_t kexec_segment_size; + +void ima_clear_kexec_file(void) +{ + vfree(ima_kexec_file.buf); + ima_kexec_file.buf = NULL; + ima_kexec_file.size = 0; + ima_kexec_file.read_pos = 0; + ima_kexec_file.count = 0; +} + +static int ima_allocate_buf_at_kexec_load(void) +{ + if ((kexec_segment_size == 0) || + (kexec_segment_size == ULONG_MAX) || + ((kexec_segment_size >> PAGE_SHIFT) > totalram_pages() / 2)) { + pr_err("%s: Invalid segment size for kexec: %zu\n", + __func__, kexec_segment_size); + return -EINVAL; + } + + /* if kexec load was called before, clear the existing buffer + * before allocating a new one + */ + if (ima_kexec_file.buf) + ima_clear_kexec_file(); + + /* segment size can't change between kexec load and execute */ + ima_kexec_file.buf = vmalloc(kexec_segment_size); + if (!ima_kexec_file.buf) { + pr_err("%s: No memory for ima kexec measurement buffer\n", + __func__); + return -ENOMEM; + } + + ima_kexec_file.size = kexec_segment_size; + ima_kexec_file.read_pos = 0; + ima_kexec_file.count = sizeof(ima_khdr); /* reserved space */ + + memset(&ima_khdr, 0, sizeof(ima_khdr)); + ima_khdr.version = 1; + + return 0; +} + static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer, unsigned long segment_size) { From patchwork Mon Jul 3 21:57:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 13300501 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 C6E21C001B1 for ; Mon, 3 Jul 2023 21:57:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231415AbjGCV5V (ORCPT ); Mon, 3 Jul 2023 17:57:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60952 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231404AbjGCV5T (ORCPT ); Mon, 3 Jul 2023 17:57:19 -0400 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id C9CCC1A1 for ; Mon, 3 Jul 2023 14:57:18 -0700 (PDT) Received: from tushar-HP-Pavilion-Laptop-15-eg0xxx.lan (c-98-237-170-177.hsd1.wa.comcast.net [98.237.170.177]) by linux.microsoft.com (Postfix) with ESMTPSA id 17AD920C08E6; Mon, 3 Jul 2023 14:57:18 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 17AD920C08E6 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1688421438; bh=QSvlPzRxeFbeULzyjZwN/RPvVC6e2A3pn0e54sScUOg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TBh2Sg92sT83le5olP6H2y5ygM6Vg6+PyI6OxTsBV0YLUk+L2zOPcZZdKHqlORane W19FFtESmi88heWz0c0dtaXJDq8J/+rg4Pwv9avmAcKEe2GqqcTXOm0fnW3tYcomhU edSdZsYhiTK7eiIBB3wE8dVxKHSx2FkeJOeWBWGM= From: Tushar Sugandhi To: zohar@linux.ibm.com, noodles@fb.com, bauermann@kolabnow.com, kexec@lists.infradead.org, linux-integrity@vger.kernel.org Cc: code@tyhicks.com, nramas@linux.microsoft.com, paul@paul-moore.com Subject: [PATCH 02/10] ima: implement function to populate buffer at kexec execute Date: Mon, 3 Jul 2023 14:57:01 -0700 Message-Id: <20230703215709.1195644-3-tusharsu@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230703215709.1195644-1-tusharsu@linux.microsoft.com> References: <20230703215709.1195644-1-tusharsu@linux.microsoft.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org There is no existing IMA functionality to just populate the buffer at kexec execute with IMA measurements. Implement a function to iterate over ima_measurements and populate the ima_kexec_file buffer. After the loop, populate ima_khdr with buffer details (version, buffer size, number of measurements). Copy the ima_khdr data into ima_kexec_file.buf and update buffer_size and buffer. The patch assumes that the ima_kexec_file.size is sufficient to hold all the measurements. It returns an error and does not handle scenarios where additional space might be needed. Signed-off-by: Tushar Sugandhi --- security/integrity/ima/ima_kexec.c | 52 ++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c index 48a683874044..858b67689701 100644 --- a/security/integrity/ima/ima_kexec.c +++ b/security/integrity/ima/ima_kexec.c @@ -62,6 +62,58 @@ static int ima_allocate_buf_at_kexec_load(void) return 0; } +static int ima_populate_buf_at_kexec_execute(unsigned long *buffer_size, void **buffer) +{ + struct ima_queue_entry *qe; + int ret = 0; + + /* + * Ensure the kexec buffer is large enough to hold ima_khdr + */ + if (ima_kexec_file.size < sizeof(ima_khdr)) { + pr_err("%s: Kexec buffer size too low to hold ima_khdr\n", + __func__); + ima_clear_kexec_file(); + return -ENOMEM; + } + + list_for_each_entry_rcu(qe, &ima_measurements, later) { + if (ima_kexec_file.count < ima_kexec_file.size) { + ima_khdr.count++; + ima_measurements_show(&ima_kexec_file, qe); + } else { + ret = -ENOMEM; + pr_err("%s: Kexec ima_measurements buffer too small\n", + __func__); + break; + } + } + if (ret < 0) + goto out; + + /* + * fill in reserved space with some buffer details + * (eg. version, buffer size, number of measurements) + */ + ima_khdr.buffer_size = ima_kexec_file.count; + if (ima_canonical_fmt) { + ima_khdr.version = cpu_to_le16(ima_khdr.version); + ima_khdr.count = cpu_to_le64(ima_khdr.count); + ima_khdr.buffer_size = cpu_to_le64(ima_khdr.buffer_size); + } + + memcpy(ima_kexec_file.buf, &ima_khdr, sizeof(ima_khdr)); + *buffer_size = ima_kexec_file.count; + *buffer = ima_kexec_file.buf; + +out: + if (ret < 0) + ima_clear_kexec_file(); + + return ret; +} + + static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer, unsigned long segment_size) { From patchwork Mon Jul 3 21:57:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 13300500 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 9EC53C001DB for ; Mon, 3 Jul 2023 21:57:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231419AbjGCV5V (ORCPT ); Mon, 3 Jul 2023 17:57:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60958 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231409AbjGCV5U (ORCPT ); Mon, 3 Jul 2023 17:57:20 -0400 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 24ED0E58 for ; Mon, 3 Jul 2023 14:57:19 -0700 (PDT) Received: from tushar-HP-Pavilion-Laptop-15-eg0xxx.lan (c-98-237-170-177.hsd1.wa.comcast.net [98.237.170.177]) by linux.microsoft.com (Postfix) with ESMTPSA id 79AE720C08E7; Mon, 3 Jul 2023 14:57:18 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 79AE720C08E7 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1688421438; bh=0H385rr4xvv2DCWeqKIKQV5s1y2DVPMF7eZDISj7L0s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NSVf05PhU8/5t+iU4STAK+h9lawJ/Oq58BG3TG2kS6zP2adxu0b6vPS9OXmdKU0Qi +dmZnQiLTWeTwaYoj4eujuKJIyZjuVFooBOnyXgrCirfaye7sM6tINN5nX/yZbO0QA wppF1MNyGYUPQZHZT6gJYp94PHDEJaFPMMU9vEdI= From: Tushar Sugandhi To: zohar@linux.ibm.com, noodles@fb.com, bauermann@kolabnow.com, kexec@lists.infradead.org, linux-integrity@vger.kernel.org Cc: code@tyhicks.com, nramas@linux.microsoft.com, paul@paul-moore.com Subject: [PATCH 03/10] ima: allocate buffer at kexec load to hold ima measurements Date: Mon, 3 Jul 2023 14:57:02 -0700 Message-Id: <20230703215709.1195644-4-tusharsu@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230703215709.1195644-1-tusharsu@linux.microsoft.com> References: <20230703215709.1195644-1-tusharsu@linux.microsoft.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org The IMA subsystem needs a dedicated mechanism to reserve extra memory for measurements added between the kexec 'load' and kexec 'execute'. Update ima_add_kexec_buffer to allocate a buffer of a sufficient size taking ima binary runtime measurements size, size of ima_kexec_hdr, and IMA_KEXEC_EXTRA_SIZE into account. Adjust the kexec_segment_size to align to the PAGE_SIZE. Call ima_allocate_buf_at_kexec_load() to allocate the buffer. This patch assumes the extra space defined (IMA_KEXEC_EXTRA_SIZE) is sufficient to handle the additional measurements. This should be as per the system requirements and based on the number of additional measurements expected during the window from kexec 'load' to kexec 'execute'. Signed-off-by: Tushar Sugandhi --- security/integrity/ima/ima.h | 2 ++ security/integrity/ima/ima_kexec.c | 21 ++++++++++----------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index c29db699c996..2ffda9449b9b 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -43,6 +43,8 @@ enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8, TPM_PCR10 = 10 }; #define NR_BANKS(chip) ((chip != NULL) ? chip->nr_allocated_banks : 0) +#define IMA_KEXEC_EXTRA_SIZE (16 * PAGE_SIZE) + /* current content of the policy */ extern int ima_policy_flag; diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c index 858b67689701..7deb8df31485 100644 --- a/security/integrity/ima/ima_kexec.c +++ b/security/integrity/ima/ima_kexec.c @@ -188,31 +188,30 @@ void ima_add_kexec_buffer(struct kimage *image) /* use more understandable variable names than defined in kbuf */ void *kexec_buffer = NULL; size_t kexec_buffer_size; - size_t kexec_segment_size; int ret; /* - * Reserve an extra half page of memory for additional measurements - * added during the kexec load. + * Reserve extra memory for measurements added in the window from + * kexec 'load' to kexec 'execute'. */ - binary_runtime_size = ima_get_binary_runtime_size(); + binary_runtime_size = ima_get_binary_runtime_size() + + sizeof(struct ima_kexec_hdr) + + IMA_KEXEC_EXTRA_SIZE; + if (binary_runtime_size >= ULONG_MAX - PAGE_SIZE) kexec_segment_size = ULONG_MAX; else - kexec_segment_size = ALIGN(ima_get_binary_runtime_size() + - PAGE_SIZE / 2, PAGE_SIZE); + kexec_segment_size = ALIGN(binary_runtime_size, PAGE_SIZE); + if ((kexec_segment_size == ULONG_MAX) || ((kexec_segment_size >> PAGE_SHIFT) > totalram_pages() / 2)) { pr_err("Binary measurement list too large.\n"); return; } - ima_dump_measurement_list(&kexec_buffer_size, &kexec_buffer, - kexec_segment_size); - if (!kexec_buffer) { - pr_err("Not enough memory for the kexec measurement buffer.\n"); + ret = ima_allocate_buf_at_kexec_load(); + if (ret < 0) return; - } kbuf.buffer = kexec_buffer; kbuf.bufsz = kexec_buffer_size; From patchwork Mon Jul 3 21:57:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 13300499 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 33B38C0015E for ; Mon, 3 Jul 2023 21:57:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230206AbjGCV5V (ORCPT ); Mon, 3 Jul 2023 17:57:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60962 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231403AbjGCV5U (ORCPT ); Mon, 3 Jul 2023 17:57:20 -0400 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 77F45E5B for ; Mon, 3 Jul 2023 14:57:19 -0700 (PDT) Received: from tushar-HP-Pavilion-Laptop-15-eg0xxx.lan (c-98-237-170-177.hsd1.wa.comcast.net [98.237.170.177]) by linux.microsoft.com (Postfix) with ESMTPSA id CAB5220C08E8; Mon, 3 Jul 2023 14:57:18 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com CAB5220C08E8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1688421439; bh=dY4aFxIDs6EY00F0s6UDoHjuv7HPfWOrldANuBkGFWU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EUeufRn/WOcR0527Xs7EmfGHRPuXdmUeyzABRAmpyU/Cn5BjjQ3ciTrKQyapp9t0S oexM5A/c9kw7UxVncX5t39AsRe26OL5vitK/cjy0SFR6+pNB6JpwVZU7l2UIWGbyNG u7/6Y7l+nL3Prp+IPlcyJoiaxnA29fz83dpICOiE= From: Tushar Sugandhi To: zohar@linux.ibm.com, noodles@fb.com, bauermann@kolabnow.com, kexec@lists.infradead.org, linux-integrity@vger.kernel.org Cc: code@tyhicks.com, nramas@linux.microsoft.com, paul@paul-moore.com Subject: [PATCH 04/10] ima: implement functions to suspend and resume measurements Date: Mon, 3 Jul 2023 14:57:03 -0700 Message-Id: <20230703215709.1195644-5-tusharsu@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230703215709.1195644-1-tusharsu@linux.microsoft.com> References: <20230703215709.1195644-1-tusharsu@linux.microsoft.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org The IMA subsystem needs to provide a mechanism to suspend or resume measurements. This functionality is needed to temporarily halt the recording of IMA measurements during certain system operations. Add functions ima_measurements_suspend() and ima_measurements_resume() functions to set and reset the suspend_ima_measurements variable, respectively, to suspend/resume IMA measurements. Use ima_extend_list_mutex to ensure that the operations are thread-safe. Note: Use ima_measurements_suspend() and ima_measurements_resume() in pairs to avoid indefinitely suspending IMA measurements. Signed-off-by: Tushar Sugandhi --- security/integrity/ima/ima.h | 2 ++ security/integrity/ima/ima_queue.c | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index 2ffda9449b9b..7127c5cf1909 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -163,6 +163,8 @@ bool ima_template_has_modsig(const struct ima_template_desc *ima_template); int ima_restore_measurement_entry(struct ima_template_entry *entry); int ima_restore_measurement_list(loff_t bufsize, void *buf); int ima_measurements_show(struct seq_file *m, void *v); +void ima_measurements_suspend(void); +void ima_measurements_resume(void); unsigned long ima_get_binary_runtime_size(void); int ima_init_template(void); void ima_init_template_list(void); diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c index 532da87ce519..cb9abc02a304 100644 --- a/security/integrity/ima/ima_queue.c +++ b/security/integrity/ima/ima_queue.c @@ -44,6 +44,11 @@ struct ima_h_table ima_htable = { */ static DEFINE_MUTEX(ima_extend_list_mutex); +/* + * Used internally by the kernel to suspend-resume ima measurements. + */ +static atomic_t suspend_ima_measurements; + /* 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) @@ -148,6 +153,20 @@ static int ima_pcr_extend(struct tpm_digest *digests_arg, int pcr) return result; } +void ima_measurements_suspend(void) +{ + mutex_lock(&ima_extend_list_mutex); + atomic_set(&suspend_ima_measurements, 1); + mutex_unlock(&ima_extend_list_mutex); +} + +void ima_measurements_resume(void) +{ + mutex_lock(&ima_extend_list_mutex); + atomic_set(&suspend_ima_measurements, 0); + mutex_unlock(&ima_extend_list_mutex); +} + /* * Add template entry to the measurement list and hash table, and * extend the pcr. From patchwork Mon Jul 3 21:57:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 13300502 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 28A16C001B3 for ; Mon, 3 Jul 2023 21:57:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231423AbjGCV5W (ORCPT ); Mon, 3 Jul 2023 17:57:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60972 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231414AbjGCV5U (ORCPT ); Mon, 3 Jul 2023 17:57:20 -0400 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id C86A7195 for ; Mon, 3 Jul 2023 14:57:19 -0700 (PDT) Received: from tushar-HP-Pavilion-Laptop-15-eg0xxx.lan (c-98-237-170-177.hsd1.wa.comcast.net [98.237.170.177]) by linux.microsoft.com (Postfix) with ESMTPSA id 271E320C08F5; Mon, 3 Jul 2023 14:57:19 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 271E320C08F5 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1688421439; bh=BnPDGoJ+Z3iQQP7eWODZlOLENbnPQ+oha3+R2NPMATc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KJr/eV5NllbZREhRLWnmcF6pDsWGV9BgJoBaZK3m5vqn790u32+rAl3fdTIT3IPiM kqQYfP25uCWai5+GtqA7peHixgQapDF0aUq/w3NlsyGlhn8EGyChlSQCQC5vrt2VLJ pQR5Nf0c7E3mtL2uoCq0xjgkqHVzb4oqLJ4NKV2U= From: Tushar Sugandhi To: zohar@linux.ibm.com, noodles@fb.com, bauermann@kolabnow.com, kexec@lists.infradead.org, linux-integrity@vger.kernel.org Cc: code@tyhicks.com, nramas@linux.microsoft.com, paul@paul-moore.com Subject: [PATCH 05/10] kexec: implement functions to map and unmap segment to kimage Date: Mon, 3 Jul 2023 14:57:04 -0700 Message-Id: <20230703215709.1195644-6-tusharsu@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230703215709.1195644-1-tusharsu@linux.microsoft.com> References: <20230703215709.1195644-1-tusharsu@linux.microsoft.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org Currently, there's no mechanism to map and unmap segments to the kimage structure. This functionality is needed when dealing with memory segments in the context of a kexec operation. The patch adds two new functions: kimage_map_segment() and kimage_unmap_segment(). Implement kimage_map_segment() which takes a kimage pointer, an address, and a size. Ensures that the entire segment is being mapped by comparing the given address and size to each segment in the kimage's segment array. Collect the source pages that correspond to the given address range, allocate an array of pointers to these pages, and map them to a contiguous range of virtual addresses. If the mapping operation is successful, the function returns the start of this range. Otherwise, it frees the page pointer array and returns NULL. Implement kimage_unmap_segment() that takes a pointer to a segment buffer and unmaps it using vunmap(). Finally, move for_each_kimage_entry() macro to kexec.h. Note: Use kimage_map_segment() and kimage_unmap_segment() carefully to avoid memory leaks and ensure that all mapped segments are properly unmapped when they're no longer needed. Signed-off-by: Tushar Sugandhi --- include/linux/kexec.h | 13 ++++++++ kernel/kexec_core.c | 72 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 80 insertions(+), 5 deletions(-) diff --git a/include/linux/kexec.h b/include/linux/kexec.h index 22b5cd24f581..e00b8101b53b 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -490,6 +490,15 @@ static inline int arch_kexec_post_alloc_pages(void *vaddr, unsigned int pages, g static inline void arch_kexec_pre_free_pages(void *vaddr, unsigned int pages) { } #endif +#define for_each_kimage_entry(image, ptr, entry) \ + for (ptr = &image->head; (entry = *ptr) && !(entry & IND_DONE); \ + ptr = (entry & IND_INDIRECTION) ? \ + boot_phys_to_virt((entry & PAGE_MASK)) : ptr + 1) + +extern void *kimage_map_segment(struct kimage *image, + unsigned long addr, unsigned long size); +extern void kimage_unmap_segment(void *buffer); + #else /* !CONFIG_KEXEC_CORE */ struct pt_regs; struct task_struct; @@ -497,6 +506,10 @@ static inline void __crash_kexec(struct pt_regs *regs) { } static inline void crash_kexec(struct pt_regs *regs) { } static inline int kexec_should_crash(struct task_struct *p) { return 0; } static inline int kexec_crash_loaded(void) { return 0; } +static inline void *kimage_map_segment(struct kimage *image, + unsigned long addr, unsigned long size) +{ return NULL; } +static inline void kimage_unmap_segment(void *buffer) { } #define kexec_in_progress false #endif /* CONFIG_KEXEC_CORE */ diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c index 3d578c6fefee..424e303fce25 100644 --- a/kernel/kexec_core.c +++ b/kernel/kexec_core.c @@ -594,11 +594,6 @@ void kimage_terminate(struct kimage *image) *image->entry = IND_DONE; } -#define for_each_kimage_entry(image, ptr, entry) \ - for (ptr = &image->head; (entry = *ptr) && !(entry & IND_DONE); \ - ptr = (entry & IND_INDIRECTION) ? \ - boot_phys_to_virt((entry & PAGE_MASK)) : ptr + 1) - static void kimage_free_entry(kimage_entry_t entry) { struct page *page; @@ -921,6 +916,73 @@ int kimage_load_segment(struct kimage *image, return result; } +void *kimage_map_segment(struct kimage *image, + unsigned long addr, unsigned long size) +{ + unsigned long eaddr = addr + size; + unsigned long src_page_addr, dest_page_addr; + struct page **src_pages; + int i, npages; + kimage_entry_t *ptr, entry; + void *vaddr = NULL; + + /* + * Make sure that we are mapping a whole segment. + */ + for (i = 0; i < image->nr_segments; i++) { + if (addr == image->segment[i].mem && + size == image->segment[i].memsz) { + break; + } + } + + if (i == image->nr_segments) { + pr_err("%s: No segment matching [%lx, %lx)\n", __func__, + addr, eaddr); + return NULL; + } + + /* + * Collect the source pages and map them in a contiguous VA range. + */ + npages = PFN_UP(eaddr) - PFN_DOWN(addr); + src_pages = kmalloc(sizeof(*src_pages) * npages, GFP_KERNEL); + if (!src_pages) { + pr_err("%s: Could not allocate ima pages array.\n", __func__); + return NULL; + } + + i = 0; + for_each_kimage_entry(image, ptr, entry) { + if (entry & IND_DESTINATION) + dest_page_addr = entry & PAGE_MASK; + else if (entry & IND_SOURCE) { + if (dest_page_addr >= addr && dest_page_addr < eaddr) { + src_page_addr = entry & PAGE_MASK; + src_pages[i++] = phys_to_page(src_page_addr); + if (i == npages) + break; + dest_page_addr += PAGE_SIZE; + } + } + } + + /* Sanity check. */ + WARN_ON(i < npages); + + vaddr = vmap(src_pages, npages, VM_MAP, PAGE_KERNEL); + if (!vaddr) { + pr_err("%s: Could not map imap buffer.\n", __func__); + kfree(src_pages); + } + return vaddr; +} + +void kimage_unmap_segment(void *segment_buffer) +{ + vunmap(segment_buffer); +} + struct kexec_load_limit { /* Mutex protects the limit count. */ struct mutex mutex; From patchwork Mon Jul 3 21:57:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 13300503 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 8096CC001DE for ; Mon, 3 Jul 2023 21:57:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231414AbjGCV5W (ORCPT ); Mon, 3 Jul 2023 17:57:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60982 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231417AbjGCV5V (ORCPT ); Mon, 3 Jul 2023 17:57:21 -0400 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 1FB7419F for ; Mon, 3 Jul 2023 14:57:20 -0700 (PDT) Received: from tushar-HP-Pavilion-Laptop-15-eg0xxx.lan (c-98-237-170-177.hsd1.wa.comcast.net [98.237.170.177]) by linux.microsoft.com (Postfix) with ESMTPSA id 7CA1D20C08FA; Mon, 3 Jul 2023 14:57:19 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 7CA1D20C08FA DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1688421439; bh=s53o5tStuuzSkUcgt//18WizvpReGbqU0p1e6vxSELk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=FKUiDnfO8rTW9XniYBxK6bcBKeUB7OG4DIMTLeqWsCfgpxo6RMHKMPK3pWy5Ggpdn bPVR4XczWaRXt1vP99+fAVRj1whR62d8PeYpjATVYJ8sW7C3i3H0ow4UTQICKeacxa MuVvIxxVmLgBEOSKeOZJAzTMmQCESWcd0FC/yMqw= From: Tushar Sugandhi To: zohar@linux.ibm.com, noodles@fb.com, bauermann@kolabnow.com, kexec@lists.infradead.org, linux-integrity@vger.kernel.org Cc: code@tyhicks.com, nramas@linux.microsoft.com, paul@paul-moore.com Subject: [PATCH 06/10] ima: update buffer at kexec execute with ima measurements Date: Mon, 3 Jul 2023 14:57:05 -0700 Message-Id: <20230703215709.1195644-7-tusharsu@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230703215709.1195644-1-tusharsu@linux.microsoft.com> References: <20230703215709.1195644-1-tusharsu@linux.microsoft.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org In the current implementation, the measurement list is not updated in the buffer during the window between kexec load and execute. This leads to measurement loss in the buffer when transitioning from the old to the new kernel. This patch provides a way to update the measurement list in the buffer during a kexec execution. Suspending the measurements during the buffer update ensures the buffer doesn't get corrupted, or goes out of sync with TPM PCRs. Thus it ensures the integrity of measurements is maintained across kernel transitions during a kexec. Introduce a new variable ima_kexec_buffer that is used to hold the address of the IMA kexec buffer. Implement a function ima_update_kexec_buffer() that is called during kexec execute, allowing the IMA to update the measurement list with the events between kexec load and execute. First check if a kexec is in progress and if the IMA kexec buffer is initialized. If these conditions are met, suspend IMA measurements and check if the new buffer size obtained from ima_get_binary_runtime_size() is larger than the current buffer size. If the new buffer size is too large, output an error message, and resume the measurements. If the new buffer size fits, populate the new buffer with the current measurements using ima_populate_buf_at_kexec_execute() and copy it into ima_kexec_buffer. Unmap ima_kexec_buffer segment from the image. Resuming the measurements is not needed in case of successful measurements since the control is being passed to the new kernel anyways through kexec execute. However, the measurements should be resumed if there are any errors flagged in the function. Signed-off-by: Tushar Sugandhi --- security/integrity/ima/ima_kexec.c | 50 ++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c index 7deb8df31485..224d88ccfe85 100644 --- a/security/integrity/ima/ima_kexec.c +++ b/security/integrity/ima/ima_kexec.c @@ -18,6 +18,7 @@ struct seq_file ima_kexec_file; struct ima_kexec_hdr ima_khdr; static size_t kexec_segment_size; +static void *ima_kexec_buffer; void ima_clear_kexec_file(void) { @@ -230,6 +231,55 @@ void ima_add_kexec_buffer(struct kimage *image) pr_debug("kexec measurement buffer for the loaded kernel at 0x%lx.\n", kbuf.mem); } + +/* + * Called during kexec execute so that IMA can update the measurement list. + */ +static int ima_update_kexec_buffer(struct notifier_block *self, + unsigned long action, void *data) +{ + void *new_buffer = NULL; + size_t new_buffer_size, cur_buffer_size; + bool resume = false; + + if (!kexec_in_progress) { + pr_info("%s: No kexec in progress.\n", __func__); + return NOTIFY_OK; + } + + if (!ima_kexec_buffer) { + pr_err("%s: Kexec buffer not set.\n", __func__); + return NOTIFY_OK; + } + + ima_measurements_suspend(); + + cur_buffer_size = kexec_segment_size - sizeof(struct ima_kexec_hdr); + new_buffer_size = ima_get_binary_runtime_size(); + if (new_buffer_size > cur_buffer_size) { + pr_err("%s: Measurement list grew too large.\n", __func__); + resume = true; + goto out; + } + + ima_populate_buf_at_kexec_execute(&new_buffer_size, &new_buffer); + + if (!new_buffer) { + pr_err("%s: Dump measurements failed.\n", __func__); + resume = true; + goto out; + } + memcpy(ima_kexec_buffer, new_buffer, new_buffer_size); +out: + kimage_unmap_segment(ima_kexec_buffer); + ima_kexec_buffer = NULL; + + if (resume) + ima_measurements_resume(); + + return NOTIFY_OK; +} + #endif /* IMA_KEXEC */ /* From patchwork Mon Jul 3 21:57:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 13300504 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 0B325EB64DC for ; Mon, 3 Jul 2023 21:57:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231417AbjGCV5X (ORCPT ); Mon, 3 Jul 2023 17:57:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60984 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231418AbjGCV5V (ORCPT ); Mon, 3 Jul 2023 17:57:21 -0400 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 7C6321A1 for ; Mon, 3 Jul 2023 14:57:20 -0700 (PDT) Received: from tushar-HP-Pavilion-Laptop-15-eg0xxx.lan (c-98-237-170-177.hsd1.wa.comcast.net [98.237.170.177]) by linux.microsoft.com (Postfix) with ESMTPSA id D099320C08FE; Mon, 3 Jul 2023 14:57:19 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com D099320C08FE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1688421440; bh=qcx5Aa65d/0M8PqhuBesEv2N4gHSQORRxOZKyGZ74F8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=r5u2DuzGdZuk9Iw/VerUCmS8YLz6jLTt7JRHgqgwVLYLILLT6VB/MUzKb5f+tNL/o gaVYhG6pyaoUi/Puv79U/15cRH6AWLj6sATN4hVZxSdgboEezHP2xRMLb8zfceyZvH NxyMyU//JHEwsjnGRh8KbT7jEkt1bhpCcffqM6OA= From: Tushar Sugandhi To: zohar@linux.ibm.com, noodles@fb.com, bauermann@kolabnow.com, kexec@lists.infradead.org, linux-integrity@vger.kernel.org Cc: code@tyhicks.com, nramas@linux.microsoft.com, paul@paul-moore.com Subject: [PATCH 07/10] ima: remove function ima_dump_measurement_list Date: Mon, 3 Jul 2023 14:57:06 -0700 Message-Id: <20230703215709.1195644-8-tusharsu@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230703215709.1195644-1-tusharsu@linux.microsoft.com> References: <20230703215709.1195644-1-tusharsu@linux.microsoft.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org The ima_dump_measurement_list function was designed to iterate over the IMA measurement list and store each entry into a buffer. The buffer, along with its size, would be returned to the caller. However, the function is no longer required in the IMA subsystem. It previously served to dump the measurement list during the kexec 'load' operation, but this functionality has been replaced by an alternative approach in this patch series. Remove the unused ima_dump_measurement_list function from the IMA subsystem, to ensure a cleaner and more maintainable code. Signed-off-by: Tushar Sugandhi --- security/integrity/ima/ima_kexec.c | 58 ------------------------------ 1 file changed, 58 deletions(-) diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c index 224d88ccfe85..424930085c18 100644 --- a/security/integrity/ima/ima_kexec.c +++ b/security/integrity/ima/ima_kexec.c @@ -115,64 +115,6 @@ static int ima_populate_buf_at_kexec_execute(unsigned long *buffer_size, void ** } -static int ima_dump_measurement_list(unsigned long *buffer_size, void **buffer, - unsigned long segment_size) -{ - struct ima_queue_entry *qe; - struct seq_file file; - struct ima_kexec_hdr khdr; - int ret = 0; - - /* segment size can't change between kexec load and execute */ - file.buf = vmalloc(segment_size); - if (!file.buf) { - ret = -ENOMEM; - goto out; - } - - file.size = segment_size; - file.read_pos = 0; - file.count = sizeof(khdr); /* reserved space */ - - memset(&khdr, 0, sizeof(khdr)); - khdr.version = 1; - list_for_each_entry_rcu(qe, &ima_measurements, later) { - if (file.count < file.size) { - khdr.count++; - ima_measurements_show(&file, qe); - } else { - ret = -EINVAL; - break; - } - } - - if (ret < 0) - goto out; - - /* - * fill in reserved space with some buffer details - * (eg. version, buffer size, number of measurements) - */ - khdr.buffer_size = file.count; - if (ima_canonical_fmt) { - khdr.version = cpu_to_le16(khdr.version); - khdr.count = cpu_to_le64(khdr.count); - khdr.buffer_size = cpu_to_le64(khdr.buffer_size); - } - memcpy(file.buf, &khdr, sizeof(khdr)); - - print_hex_dump_debug("ima dump: ", DUMP_PREFIX_NONE, 16, 1, - file.buf, file.count < 100 ? file.count : 100, - true); - - *buffer_size = file.count; - *buffer = file.buf; -out: - if (ret == -EINVAL) - vfree(file.buf); - return ret; -} - /* * Called during kexec_file_load so that IMA can add a segment to the kexec * image for the measurement list for the next kernel. From patchwork Mon Jul 3 21:57:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 13300506 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 E4307C0015E for ; Mon, 3 Jul 2023 21:57:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231428AbjGCV5Z (ORCPT ); Mon, 3 Jul 2023 17:57:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60996 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231403AbjGCV5V (ORCPT ); Mon, 3 Jul 2023 17:57:21 -0400 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id C90FFE58 for ; Mon, 3 Jul 2023 14:57:20 -0700 (PDT) Received: from tushar-HP-Pavilion-Laptop-15-eg0xxx.lan (c-98-237-170-177.hsd1.wa.comcast.net [98.237.170.177]) by linux.microsoft.com (Postfix) with ESMTPSA id 2E33320C0900; Mon, 3 Jul 2023 14:57:20 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 2E33320C0900 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1688421440; bh=jZlpyLIYjpWzttcfW8imXFANOTtzePBpV7z2w9ly2cQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=E4ET/YXnwrZx/o2zwb9WVbHnUdn87s3v7wBVX1I4GI2yGxfzfGu27/Qcx2h9bZ58S LUhgYEaI0/x9n4hf0sISkKDkLwUCr+w2deOIKfDcfpdheYuW0KrfEfJWUTPTxyMIDv too7lIzFyrO4Oh7y1MBFrJoyBx2yKoDc/D8zXIwI= From: Tushar Sugandhi To: zohar@linux.ibm.com, noodles@fb.com, bauermann@kolabnow.com, kexec@lists.infradead.org, linux-integrity@vger.kernel.org Cc: code@tyhicks.com, nramas@linux.microsoft.com, paul@paul-moore.com Subject: [PATCH 08/10] ima: implement and register a reboot notifier function to update kexec buffer Date: Mon, 3 Jul 2023 14:57:07 -0700 Message-Id: <20230703215709.1195644-9-tusharsu@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230703215709.1195644-1-tusharsu@linux.microsoft.com> References: <20230703215709.1195644-1-tusharsu@linux.microsoft.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org The IMA subsystem needs to ensure that the measurement list is up to date during a kexec operation, i.e., when the kernel is rebooted without going through the full system reboot process. Currently, there is no mechanism to update the measurement list when the system is soft booted using kexec. Add a notifier function ima_update_kexec_buffer that is called during a kexec soft reboot. Implement ima_kexec_post_load, which maps the IMA buffer after a kexec load and registers the reboot notifier. Define a new notifier block update_buffer_nb, with ima_update_kexec_buffer as its notifier function. Register the notifier function in ima_kexec_post_load if it hasn't been already, indicated by the ima_kexec_update_registered flag. When a kexec soft reboot is triggered, ima_update_kexec_buffer will be executed to update the IMA buffer. This ensures that the events between kexec 'load' and 'execute' are captured and integrity of measurements remains intact across kexec reboots. Signed-off-by: Tushar Sugandhi --- include/linux/ima.h | 3 +++ security/integrity/ima/ima_kexec.c | 35 ++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/include/linux/ima.h b/include/linux/ima.h index 86b57757c7b1..006db20f852d 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h @@ -49,6 +49,9 @@ static inline void ima_appraise_parse_cmdline(void) {} #ifdef CONFIG_IMA_KEXEC extern void ima_add_kexec_buffer(struct kimage *image); +extern void ima_kexec_post_load(struct kimage *image); +#else +static inline void ima_kexec_post_load(struct kimage *image) {} #endif #else diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c index 424930085c18..363c107dc4a5 100644 --- a/security/integrity/ima/ima_kexec.c +++ b/security/integrity/ima/ima_kexec.c @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include "ima.h" #ifdef CONFIG_IMA_KEXEC @@ -19,6 +21,7 @@ struct seq_file ima_kexec_file; struct ima_kexec_hdr ima_khdr; static size_t kexec_segment_size; static void *ima_kexec_buffer; +static bool ima_kexec_update_registered; void ima_clear_kexec_file(void) { @@ -222,6 +225,38 @@ static int ima_update_kexec_buffer(struct notifier_block *self, return NOTIFY_OK; } +struct notifier_block update_buffer_nb = { + .notifier_call = ima_update_kexec_buffer, +}; + +/* + * Create a mapping for the source pages that contain the IMA buffer + * so we can update it later. + */ +void ima_kexec_post_load(struct kimage *image) +{ + if (ima_kexec_buffer) { + kimage_unmap_segment(ima_kexec_buffer); + ima_kexec_buffer = NULL; + } + + if (!image->ima_buffer_addr) + return; + + ima_kexec_buffer = kimage_map_segment(image, + image->ima_buffer_addr, + image->ima_buffer_size); + if (!ima_kexec_buffer) { + pr_err("%s: Could not map measurements buffer.\n", __func__); + return; + } + + if (!ima_kexec_update_registered) { + register_reboot_notifier(&update_buffer_nb); + ima_kexec_update_registered = true; + } +} + #endif /* IMA_KEXEC */ /* From patchwork Mon Jul 3 21:57:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 13300505 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 60538C001DD for ; Mon, 3 Jul 2023 21:57:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231418AbjGCV5X (ORCPT ); Mon, 3 Jul 2023 17:57:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60990 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231404AbjGCV5V (ORCPT ); Mon, 3 Jul 2023 17:57:21 -0400 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id EEED1E5B for ; Mon, 3 Jul 2023 14:57:20 -0700 (PDT) Received: from tushar-HP-Pavilion-Laptop-15-eg0xxx.lan (c-98-237-170-177.hsd1.wa.comcast.net [98.237.170.177]) by linux.microsoft.com (Postfix) with ESMTPSA id 80FE920C091F; Mon, 3 Jul 2023 14:57:20 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 80FE920C091F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1688421440; bh=gnWZBlqyn9Og/TXFeYVjeHamDdASDQOleIS25w3NzJY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BP7uwA9Z4rK9VvYzQq/a+oZbqsOSr96N5eD6OztrEuWAGoJF73lvv03v3otvWdi6J a/ZcVxEWbMTH8QmHKkaxVKNC5VATJGF3EEgrxGhKni2SM6bhCfKxi/DPZEhLzA+RpE CxMBNbGoeEZH0ggjkoRK6QcZwnYEKWCCcuTtutXw= From: Tushar Sugandhi To: zohar@linux.ibm.com, noodles@fb.com, bauermann@kolabnow.com, kexec@lists.infradead.org, linux-integrity@vger.kernel.org Cc: code@tyhicks.com, nramas@linux.microsoft.com, paul@paul-moore.com Subject: [PATCH 09/10] ima: suspend measurements while the kexec buffer is being copied Date: Mon, 3 Jul 2023 14:57:08 -0700 Message-Id: <20230703215709.1195644-10-tusharsu@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230703215709.1195644-1-tusharsu@linux.microsoft.com> References: <20230703215709.1195644-1-tusharsu@linux.microsoft.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org If the new measurements are added to the list while the kexec buffer is being copied during kexec execute, the buffer may get corrupted, or it can go out of sync with TPM PCRs. This could potentially lead to breaking the integrity of the measurements after the kexec soft reboot to the new kernel. Introduce a check in the ima_add_template_entry function not to measure events and return from the function early when the suspend_ima_measurements flag is set. This ensures the consistency of the IMA measurement list during the copying of the kexec buffer. When the suspend_ima_measurements flag is set, any new measurements will be ignored until the flag is unset. This allows the buffer to be safely copied without worrying about concurrent modifications to the measurement list. This is crucial for maintaining the integrity of the measurements during a kexec soft reboot. Signed-off-by: Tushar Sugandhi --- security/integrity/ima/ima_queue.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c index cb9abc02a304..5946a26a2849 100644 --- a/security/integrity/ima/ima_queue.c +++ b/security/integrity/ima/ima_queue.c @@ -195,6 +195,19 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation, } } + /* + * suspend_ima_measurements will be set if the system is + * undergoing kexec soft boot to a new kernel. + * suspending measurements in this short window ensures the + * consistency of the IMA measurement list during copying + * of the kexec buffer. + */ + if (atomic_read(&suspend_ima_measurements)) { + audit_cause = "measurements_suspended"; + audit_info = 0; + goto out; + } + result = ima_add_digest_entry(entry, !IS_ENABLED(CONFIG_IMA_DISABLE_HTABLE)); if (result < 0) { From patchwork Mon Jul 3 21:57:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 13300507 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 5EA45C001B1 for ; Mon, 3 Jul 2023 21:57:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231403AbjGCV5Z (ORCPT ); Mon, 3 Jul 2023 17:57:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60998 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231409AbjGCV5W (ORCPT ); Mon, 3 Jul 2023 17:57:22 -0400 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 76A65187 for ; Mon, 3 Jul 2023 14:57:21 -0700 (PDT) Received: from tushar-HP-Pavilion-Laptop-15-eg0xxx.lan (c-98-237-170-177.hsd1.wa.comcast.net [98.237.170.177]) by linux.microsoft.com (Postfix) with ESMTPSA id CF96B208FFDD; Mon, 3 Jul 2023 14:57:20 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com CF96B208FFDD DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1688421441; bh=IA4qVA7yS6tfVuU9PQyqSbjKk9N21XI0y5043nMYdXg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QGLrEABDXJHWi1bi5YE/9tRYciFa8BBH+oONcU85PCku4cyeQ0jqkVCY0h1wIVqcy h/KyREwavxt4474a6GxwSENgRdxekCa24hShwYzfX3rdsKmmSLVjku82b3VG5bb+R1 zupINlJPJ/ih+YJwakHujz/W1kM+TvaSzdCeqgqY= From: Tushar Sugandhi To: zohar@linux.ibm.com, noodles@fb.com, bauermann@kolabnow.com, kexec@lists.infradead.org, linux-integrity@vger.kernel.org Cc: code@tyhicks.com, nramas@linux.microsoft.com, paul@paul-moore.com Subject: [PATCH 10/10] kexec: update kexec_file_load syscall to call ima_kexec_post_load Date: Mon, 3 Jul 2023 14:57:09 -0700 Message-Id: <20230703215709.1195644-11-tusharsu@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230703215709.1195644-1-tusharsu@linux.microsoft.com> References: <20230703215709.1195644-1-tusharsu@linux.microsoft.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-integrity@vger.kernel.org The kexec_file_load syscall is used to load a new kernel for kexec. The syscall needs to update its function to call ima_kexec_post_load, which was implemented in a previous patch. ima_kexec_post_load takes care of mapping the measurement list for the next kernel and registering a reboot notifier if it's not already registered. Modify the kexec_file_load syscall to call ima_kexec_post_load after the image has been loaded and prepared for kexec. This ensures that the IMA measurement list will be available to the next kernel after a kexec reboot. This also ensures the measurements taken in the window between kexec load and execute are captured and passed to the next kernel. Declare the kimage_file_post_load function in the kernel/kexec_internal.h, so it can be properly used in the syscall. Signed-off-by: Tushar Sugandhi --- kernel/kexec_file.c | 7 +++++++ kernel/kexec_internal.h | 1 + 2 files changed, 8 insertions(+) diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index f989f5f1933b..efe28e77280c 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c @@ -184,6 +184,11 @@ kimage_validate_signature(struct kimage *image) } #endif +void kimage_file_post_load(struct kimage *image) +{ + ima_kexec_post_load(image); +} + /* * In file mode list of segments is prepared by kernel. Copy relevant * data from user space, do error checking, prepare segment list @@ -399,6 +404,8 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd, kimage_terminate(image); + kimage_file_post_load(image); + ret = machine_kexec_post_load(image); if (ret) goto out; diff --git a/kernel/kexec_internal.h b/kernel/kexec_internal.h index 74da1409cd14..98dd5fcafaf0 100644 --- a/kernel/kexec_internal.h +++ b/kernel/kexec_internal.h @@ -30,6 +30,7 @@ static inline void kexec_unlock(void) #ifdef CONFIG_KEXEC_FILE #include +void kimage_file_post_load(struct kimage *image); void kimage_file_post_load_cleanup(struct kimage *image); extern char kexec_purgatory[]; extern size_t kexec_purgatory_size;