From patchwork Sat Dec 16 01:07:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 13495302 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 920BA10F1 for ; Sat, 16 Dec 2023 01:07:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="kZVOoM7T" Received: from tushar-HP-Pavilion-Laptop-15-eg0xxx.lan (unknown [50.46.228.62]) by linux.microsoft.com (Postfix) with ESMTPSA id C557F2076F83; Fri, 15 Dec 2023 17:07:38 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com C557F2076F83 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1702688859; bh=x/mkgEQDVnMKkmiF91pUuCNykbAoH5A1eV70GlWiSk4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kZVOoM7To1l3vx0NF0Riz9+jr+M18tBeiOl7de1cSTNa+4ozgq/jbkrV+bVodkAMV fHREBSeHOYQxGFPO6nQvhqkLL033RUQdCzsnBTcrpg/80A/IAOHYE8ut4X+nKaEHiA uH7tyJKDF2CHG426uOaO+qNuXg5HnpdMb6FkZyoQ= From: Tushar Sugandhi To: zohar@linux.ibm.com, roberto.sassu@huaweicloud.com, roberto.sassu@huawei.com, eric.snowberg@oracle.com, stefanb@linux.ibm.com, ebiederm@xmission.com, noodles@fb.com, bauermann@kolabnow.com, linux-integrity@vger.kernel.org, kexec@lists.infradead.org Cc: code@tyhicks.com, nramas@linux.microsoft.com, paul@paul-moore.com Subject: [PATCH v3 1/7] ima: define and call ima_alloc_kexec_file_buf Date: Fri, 15 Dec 2023 17:07:23 -0800 Message-Id: <20231216010729.2904751-2-tusharsu@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231216010729.2904751-1-tusharsu@linux.microsoft.com> References: <20231216010729.2904751-1-tusharsu@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-integrity@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Refactor ima_dump_measurement_list() to move the memory allocation part to a separate function ima_alloc_kexec_file_buf() to allocate buffer of size 'kexec_segment_size' at kexec 'load'. Make the local variables in function ima_dump_measurement_list() global, so that they can be accessed from ima_alloc_kexec_file_buf(). Make necessary changes to the function ima_add_kexec_buffer() to call the above two functions. Signed-off-by: Tushar Sugandhi --- security/integrity/ima/ima_kexec.c | 96 +++++++++++++++++++++--------- 1 file changed, 67 insertions(+), 29 deletions(-) diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c index 419dc405c831..ae27101d0615 100644 --- a/security/integrity/ima/ima_kexec.c +++ b/security/integrity/ima/ima_kexec.c @@ -15,62 +15,93 @@ #include "ima.h" #ifdef CONFIG_IMA_KEXEC +struct seq_file ima_kexec_file; + +void ima_free_kexec_file_buf(struct seq_file *sf) +{ + vfree(sf->buf); + sf->buf = NULL; + sf->size = 0; + sf->read_pos = 0; + sf->count = 0; +} + +static int ima_alloc_kexec_file_buf(size_t segment_size) +{ + /* + * kexec 'load' may be called multiple times. + * Free and realloc the buffer only if the segment_size is + * changed from the previous kexec 'load' call. + */ + if (ima_kexec_file.buf && + ima_kexec_file.size == segment_size && + ima_kexec_file.read_pos == 0 && + ima_kexec_file.count == sizeof(struct ima_kexec_hdr)) + return 0; + + ima_free_kexec_file_buf(&ima_kexec_file); + + /* segment size can't change between kexec load and execute */ + ima_kexec_file.buf = vmalloc(segment_size); + if (!ima_kexec_file.buf) + return -ENOMEM; + + ima_kexec_file.size = segment_size; + ima_kexec_file.read_pos = 0; + ima_kexec_file.count = sizeof(struct ima_kexec_hdr); /* reserved space */ + + return 0; +} + 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; + if (!ima_kexec_file.buf) { + *buffer_size = 0; + *buffer = NULL; + pr_err("%s: Kexec file buf not allocated\n", __func__); + return -EINVAL; } - file.size = segment_size; - file.read_pos = 0; - file.count = sizeof(khdr); /* reserved space */ - memset(&khdr, 0, sizeof(khdr)); khdr.version = 1; + + /* Copy as many IMA measurements list records as possible */ list_for_each_entry_rcu(qe, &ima_measurements, later) { - if (file.count < file.size) { + if (ima_kexec_file.count < ima_kexec_file.size) { khdr.count++; - ima_measurements_show(&file, qe); + ima_measurements_show(&ima_kexec_file, qe); } else { - ret = -EINVAL; + pr_err("%s: IMA log file is too big for Kexec buf\n", + __func__); 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; + khdr.buffer_size = ima_kexec_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)); + memcpy(ima_kexec_file.buf, &khdr, sizeof(khdr)); print_hex_dump_debug("ima dump: ", DUMP_PREFIX_NONE, 16, 1, - file.buf, file.count < 100 ? file.count : 100, + ima_kexec_file.buf, ima_kexec_file.count < 100 ? + ima_kexec_file.count : 100, true); - *buffer_size = file.count; - *buffer = file.buf; -out: - if (ret == -EINVAL) - vfree(file.buf); - return ret; + *buffer_size = ima_kexec_file.count; + *buffer = ima_kexec_file.buf; + + return 0; } /* @@ -108,13 +139,20 @@ void ima_add_kexec_buffer(struct kimage *image) return; } - ima_dump_measurement_list(&kexec_buffer_size, &kexec_buffer, - kexec_segment_size); - if (!kexec_buffer) { + ret = ima_alloc_kexec_file_buf(kexec_segment_size); + if (ret < 0) { pr_err("Not enough memory for the kexec measurement buffer.\n"); return; } + ret = ima_dump_measurement_list(&kexec_buffer_size, &kexec_buffer, + kexec_segment_size); + if (ret < 0) { + pr_err("%s: Failed to dump IMA measurements. Error:%d.\n", + __func__, ret); + return; + } + kbuf.buffer = kexec_buffer; kbuf.bufsz = kexec_buffer_size; kbuf.memsz = kexec_segment_size; From patchwork Sat Dec 16 01:07:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 13495303 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id C6E1F10FE for ; Sat, 16 Dec 2023 01:07:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="r0fwN/AD" Received: from tushar-HP-Pavilion-Laptop-15-eg0xxx.lan (unknown [50.46.228.62]) by linux.microsoft.com (Postfix) with ESMTPSA id 425D92076F87; Fri, 15 Dec 2023 17:07:39 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 425D92076F87 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1702688859; bh=IKFadLdNr1wjeUBEBwQBCsj9pGjOw1vl+gw5TjhUdIw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=r0fwN/ADMDFhLiBA7zf/4GHpNj1gJlm3tJvFguZdmZ9DDw+tkI7aGW4Cyi4Fhew8I 5B8HMy7UtfJpIRxJeHJdOZrXKGrLGMo3R5NM7OC3YI8R52uVZSUumYJZ9+ne/bqc50 Bnkcd9AVvuvVR6PAZwiPDaFWPkNs2Bh26VfuJ3wA= From: Tushar Sugandhi To: zohar@linux.ibm.com, roberto.sassu@huaweicloud.com, roberto.sassu@huawei.com, eric.snowberg@oracle.com, stefanb@linux.ibm.com, ebiederm@xmission.com, noodles@fb.com, bauermann@kolabnow.com, linux-integrity@vger.kernel.org, kexec@lists.infradead.org Cc: code@tyhicks.com, nramas@linux.microsoft.com, paul@paul-moore.com Subject: [PATCH v3 2/7] ima: kexec: move ima log copy from kexec load to execute Date: Fri, 15 Dec 2023 17:07:24 -0800 Message-Id: <20231216010729.2904751-3-tusharsu@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231216010729.2904751-1-tusharsu@linux.microsoft.com> References: <20231216010729.2904751-1-tusharsu@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-integrity@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 ima_dump_measurement_list() is called from ima_add_kexec_buffer() during kexec 'load', which may result in loss of IMA measurements between kexec 'load' and 'execute'. It needs to be called during kexec 'execute'. Implement ima_update_kexec_buffer(), to be called during kexec 'execute'. Move ima_dump_measurement_list() function call from ima_add_kexec_buffer() to ima_update_kexec_buffer(). Make the needed variables global for accessibility during kexec 'load' and 'execute'. Implement and call ima_measurements_suspend() and ima_measurements_resume() to help ensure the integrity of the IMA log during copy. Add a reboot notifier_block to trigger ima_update_kexec_buffer() during kexec soft-reboot. Exclude ima segment from calculating and storing digest in function kexec_calculate_store_digests(), since ima segment can be modified after the digest is computed during kexec 'load'. Signed-off-by: Tushar Sugandhi --- include/linux/kexec.h | 3 ++ kernel/kexec_file.c | 8 ++++ security/integrity/ima/ima.h | 2 + security/integrity/ima/ima_kexec.c | 61 +++++++++++++++++++++++++----- security/integrity/ima/ima_queue.c | 19 ++++++++++ 5 files changed, 84 insertions(+), 9 deletions(-) diff --git a/include/linux/kexec.h b/include/linux/kexec.h index 22b5cd24f581..fd94404acc66 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -366,6 +366,9 @@ struct kimage { phys_addr_t ima_buffer_addr; size_t ima_buffer_size; + + unsigned long ima_segment_index; + bool is_ima_segment_index_set; #endif /* Core ELF header buffer */ diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index f989f5f1933b..bf758fd5062c 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c @@ -734,6 +734,14 @@ static int kexec_calculate_store_digests(struct kimage *image) if (ksegment->kbuf == pi->purgatory_buf) continue; + /* + * Skip the segment if ima_segment_index is set and matches + * the current index + */ + if (image->is_ima_segment_index_set && + i == image->ima_segment_index) + continue; + ret = crypto_shash_update(desc, ksegment->kbuf, ksegment->bufsz); if (ret) diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h index c29db699c996..49a6047dd8eb 100644 --- a/security/integrity/ima/ima.h +++ b/security/integrity/ima/ima.h @@ -161,6 +161,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_kexec.c b/security/integrity/ima/ima_kexec.c index ae27101d0615..0063d5e7b634 100644 --- a/security/integrity/ima/ima_kexec.c +++ b/security/integrity/ima/ima_kexec.c @@ -16,6 +16,8 @@ #ifdef CONFIG_IMA_KEXEC struct seq_file ima_kexec_file; +static void *ima_kexec_buffer; +static size_t kexec_segment_size; void ima_free_kexec_file_buf(struct seq_file *sf) { @@ -120,7 +122,6 @@ 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; /* @@ -145,17 +146,10 @@ void ima_add_kexec_buffer(struct kimage *image) return; } - ret = ima_dump_measurement_list(&kexec_buffer_size, &kexec_buffer, - kexec_segment_size); - if (ret < 0) { - pr_err("%s: Failed to dump IMA measurements. Error:%d.\n", - __func__, ret); - return; - } - kbuf.buffer = kexec_buffer; kbuf.bufsz = kexec_buffer_size; kbuf.memsz = kexec_segment_size; + image->is_ima_segment_index_set = false; ret = kexec_add_buffer(&kbuf); if (ret) { pr_err("Error passing over kexec measurement buffer.\n"); @@ -166,10 +160,59 @@ void ima_add_kexec_buffer(struct kimage *image) image->ima_buffer_addr = kbuf.mem; image->ima_buffer_size = kexec_segment_size; image->ima_buffer = kexec_buffer; + image->ima_segment_index = image->nr_segments - 1; + image->is_ima_segment_index_set = true; 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 *buf = NULL; + size_t buf_size; + bool resume = false; + int ret = NOTIFY_OK; + + if (!kexec_in_progress) { + pr_info("%s: No kexec in progress.\n", __func__); + return ret; + } + + if (!ima_kexec_buffer) { + pr_err("%s: Kexec buffer not set.\n", __func__); + return ret; + } + + ima_measurements_suspend(); + + ret = ima_dump_measurement_list(&buf_size, &buf, + kexec_segment_size); + + if (!buf) { + pr_err("%s: Dump measurements failed. Error:%d\n", + __func__, ret); + resume = true; + goto out; + } + memcpy(ima_kexec_buffer, buf, buf_size); +out: + ima_kexec_buffer = NULL; + + if (resume) + ima_measurements_resume(); + + return ret; +} + +struct notifier_block update_buffer_nb = { + .notifier_call = ima_update_kexec_buffer, +}; + #endif /* IMA_KEXEC */ /* 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 Sat Dec 16 01:07:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 13495307 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 359FB1106 for ; Sat, 16 Dec 2023 01:07:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="C8hPoGvc" Received: from tushar-HP-Pavilion-Laptop-15-eg0xxx.lan (unknown [50.46.228.62]) by linux.microsoft.com (Postfix) with ESMTPSA id 7E6402076F97; Fri, 15 Dec 2023 17:07:39 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 7E6402076F97 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1702688859; bh=WRUE4Clb8fnKLP41fDDCg3tM3zzmPHm2nOglKL89s2E=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=C8hPoGvcmAnBn++ieHTbpOQi8WiRDANFkxuC2zvc0wbxcd+pHIU9RpDL0K9lL6FvN FIwCj/750LoXesQrLZ1cBtVsdRJPFVToTL3VQm7i1EF9tgazve89DbozeYRCYgx6VM 24wCySciVx69P/jqROjokQ2xhvT4tmpC6uQkjxLM= From: Tushar Sugandhi To: zohar@linux.ibm.com, roberto.sassu@huaweicloud.com, roberto.sassu@huawei.com, eric.snowberg@oracle.com, stefanb@linux.ibm.com, ebiederm@xmission.com, noodles@fb.com, bauermann@kolabnow.com, linux-integrity@vger.kernel.org, kexec@lists.infradead.org Cc: code@tyhicks.com, nramas@linux.microsoft.com, paul@paul-moore.com Subject: [PATCH v3 3/7] ima: kexec: map IMA buffer source pages to image after kexec load Date: Fri, 15 Dec 2023 17:07:25 -0800 Message-Id: <20231216010729.2904751-4-tusharsu@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231216010729.2904751-1-tusharsu@linux.microsoft.com> References: <20231216010729.2904751-1-tusharsu@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-integrity@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Implement kimage_map_segment() to enable mapping of IMA buffer source pages to the kimage structure post kexec 'load'. This function, accepting a kimage pointer, an address, and a size, will gather the source pages within the specified address range, create an array of page pointers, and map these to a contiguous virtual address range. The function returns the start of this range if successful, or NULL if unsuccessful. Additionally, introduce kimage_unmap_segment() for unmapping segments using vunmap(). Introduce ima_kexec_post_load(), to be invoked by IMA following the kexec 'load' of the new Kernel image. This function will map the IMA buffer, allocated during kexec 'load', to a segment in the loaded image. Lastly, relocate the for_each_kimage_entry() macro from kexec_core.c to kexec.h for broader accessibility. Signed-off-by: Tushar Sugandhi --- include/linux/ima.h | 3 ++ include/linux/kexec.h | 13 +++++++ kernel/kexec_core.c | 59 +++++++++++++++++++++++++++--- security/integrity/ima/ima_kexec.c | 32 ++++++++++++++++ 4 files changed, 102 insertions(+), 5 deletions(-) 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/include/linux/kexec.h b/include/linux/kexec.h index fd94404acc66..eb98aca7f4c7 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -493,6 +493,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; @@ -500,6 +509,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..26978ad02676 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,60 @@ 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; + unsigned int npages; + struct page **src_pages; + int i; + kimage_entry_t *ptr, entry; + void *vaddr = NULL; + + /* + * Collect the source pages and map them in a contiguous VA range. + */ + npages = PFN_UP(eaddr) - PFN_DOWN(addr); + src_pages = kmalloc_array(npages, sizeof(*src_pages), 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++] = + virt_to_page(__va(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); + kfree(src_pages); + + if (!vaddr) + pr_err("%s: Could not map imap buffer.\n", __func__); + + return vaddr; +} + +void kimage_unmap_segment(void *segment_buffer) +{ + vunmap(segment_buffer); +} + struct kexec_load_limit { /* Mutex protects the limit count. */ struct mutex mutex; diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c index 0063d5e7b634..55bd5362262e 100644 --- a/security/integrity/ima/ima_kexec.c +++ b/security/integrity/ima/ima_kexec.c @@ -12,12 +12,15 @@ #include #include #include +#include +#include #include "ima.h" #ifdef CONFIG_IMA_KEXEC struct seq_file ima_kexec_file; static void *ima_kexec_buffer; static size_t kexec_segment_size; +static bool ima_kexec_update_registered; void ima_free_kexec_file_buf(struct seq_file *sf) { @@ -201,6 +204,7 @@ static int ima_update_kexec_buffer(struct notifier_block *self, } memcpy(ima_kexec_buffer, buf, buf_size); out: + kimage_unmap_segment(ima_kexec_buffer); ima_kexec_buffer = NULL; if (resume) @@ -213,6 +217,34 @@ 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 Sat Dec 16 01:07:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 13495304 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 65E131108 for ; Sat, 16 Dec 2023 01:07:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="GU/bb5Un" Received: from tushar-HP-Pavilion-Laptop-15-eg0xxx.lan (unknown [50.46.228.62]) by linux.microsoft.com (Postfix) with ESMTPSA id EA10920B3CC1; Fri, 15 Dec 2023 17:07:39 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com EA10920B3CC1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1702688860; bh=F9K7Rc9TpRNNFu6bus4pmdllRgh3199Skv9ZQY0T4F4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GU/bb5UnCHXdTAijfRo8dmDKT43lYFPcnqtovspj7ZNB1YY9gROuyuNHlcAw+r1ea 04V9ylonliFf4XvbMBBVYQF6iRGns4+rJoRYHaMt/zyk+ufpXOZdkauKukoDbhfX7a VdB1rTanfcAYntWkGGDcnO1rvsdJ+/WSOZBJ+fH0= From: Tushar Sugandhi To: zohar@linux.ibm.com, roberto.sassu@huaweicloud.com, roberto.sassu@huawei.com, eric.snowberg@oracle.com, stefanb@linux.ibm.com, ebiederm@xmission.com, noodles@fb.com, bauermann@kolabnow.com, linux-integrity@vger.kernel.org, kexec@lists.infradead.org Cc: code@tyhicks.com, nramas@linux.microsoft.com, paul@paul-moore.com Subject: [PATCH v3 4/7] kexec: update kexec_file_load syscall to alloc ima buffer after load Date: Fri, 15 Dec 2023 17:07:26 -0800 Message-Id: <20231216010729.2904751-5-tusharsu@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231216010729.2904751-1-tusharsu@linux.microsoft.com> References: <20231216010729.2904751-1-tusharsu@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-integrity@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Implement function kimage_file_post_load() to call ima_kexec_post_load() This ensures the IMA buffer allocated at kexec 'load' is mapped to a segment in the next loaded Kernel image. Modify the kexec_file_load() syscall to call kimage_file_post_load() after the image has been loaded and prepared for kexec. Call the function kimage_file_post_load() only for kexec soft reboot scenarios and not for KEXEC_FILE_ON_CRASH scenarios. Signed-off-by: Tushar Sugandhi --- kernel/kexec_file.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index bf758fd5062c..ee38799ff1a3 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,9 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd, kimage_terminate(image); + if (!(flags & KEXEC_FILE_ON_CRASH)) + kimage_file_post_load(image); + ret = machine_kexec_post_load(image); if (ret) goto out; From patchwork Sat Dec 16 01:07:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 13495305 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id DA6D5110E for ; Sat, 16 Dec 2023 01:07:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="V3FEDbdT" Received: from tushar-HP-Pavilion-Laptop-15-eg0xxx.lan (unknown [50.46.228.62]) by linux.microsoft.com (Postfix) with ESMTPSA id 30F9C20B3CC2; Fri, 15 Dec 2023 17:07:40 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 30F9C20B3CC2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1702688860; bh=2IOw2XXOJ/lRQNX6HMUntrseQX7ML13OzSk1lyP6kFQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=V3FEDbdTk51T+KVYtJxwjl13Kg8iXAPKVPl3td9AhQHoPc/OE4TEWuzeLyvMEHQOz PhqkdxOePFRhhx466L0EOOEhMU+5aNfgfXcQWxk68Q9fGhunFEwqVr4Iw27NefnU9T Ue/UZEnfo15HpXR2GvKuE5bECHHxBeraTWqNMjn0= From: Tushar Sugandhi To: zohar@linux.ibm.com, roberto.sassu@huaweicloud.com, roberto.sassu@huawei.com, eric.snowberg@oracle.com, stefanb@linux.ibm.com, ebiederm@xmission.com, noodles@fb.com, bauermann@kolabnow.com, linux-integrity@vger.kernel.org, kexec@lists.infradead.org Cc: code@tyhicks.com, nramas@linux.microsoft.com, paul@paul-moore.com Subject: [PATCH v3 5/7] ima: suspend measurements during buffer copy at kexec execute Date: Fri, 15 Dec 2023 17:07:27 -0800 Message-Id: <20231216010729.2904751-6-tusharsu@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231216010729.2904751-1-tusharsu@linux.microsoft.com> References: <20231216010729.2904751-1-tusharsu@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-integrity@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 If the new measurements are added to the IMA log while it is being being copied to the kexec buffer during kexec 'execute', it can miss copying those new measurements to the kexec buffer, and the buffer can go out of sync with TPM PCRs. This could result in breaking the integrity of the measurements after the kexec soft reboot to the new Kernel. Add a check in the ima_add_template_entry() function not to measure events and return from the function early when 'suspend_ima_measurements' flag is set. This ensures the consistency of the IMA measurement list while copying them to 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 Sat Dec 16 01:07:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 13495308 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id DA7041116 for ; Sat, 16 Dec 2023 01:07:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="mNPb2AIu" Received: from tushar-HP-Pavilion-Laptop-15-eg0xxx.lan (unknown [50.46.228.62]) by linux.microsoft.com (Postfix) with ESMTPSA id 6B37520B3CC4; Fri, 15 Dec 2023 17:07:40 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 6B37520B3CC4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1702688860; bh=Kuh7HHtW0surZQmmoh5+OnSpf7Wv3yhg4QwvyIeBjLQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mNPb2AIur58OR3dj8b86eQdW3bzbIccak3QFeUC8oydKG1wbr6xpxeuGYUhoGr+Jw 8J6BpxZDw68QpOohLkDytm/j6cRBoX9+Jm++2hXVUG24qEHdcHd1Lbreb2NOBiei/O V6lYA183wfPY//gDdsrR1M5r8XJivJDPr301UZMg= From: Tushar Sugandhi To: zohar@linux.ibm.com, roberto.sassu@huaweicloud.com, roberto.sassu@huawei.com, eric.snowberg@oracle.com, stefanb@linux.ibm.com, ebiederm@xmission.com, noodles@fb.com, bauermann@kolabnow.com, linux-integrity@vger.kernel.org, kexec@lists.infradead.org Cc: code@tyhicks.com, nramas@linux.microsoft.com, paul@paul-moore.com Subject: [PATCH v3 6/7] ima: configure memory to log events between kexec load and execute Date: Fri, 15 Dec 2023 17:07:28 -0800 Message-Id: <20231216010729.2904751-7-tusharsu@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231216010729.2904751-1-tusharsu@linux.microsoft.com> References: <20231216010729.2904751-1-tusharsu@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-integrity@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 IMA currently allocates half a PAGE_SIZE for the extra events that would be measured between kexec 'load' and 'execute'. Depending on the IMA policy and the system state, that memory may not be sufficient to hold the extra IMA events measured after kexec 'load'. The memory requirements vary from system to system and they should be configurable. Define a Kconfig option, IMA_KEXEC_EXTRA_MEMORY_KB, to configure the extra memory (in kb) to be allocated for IMA measurements added in the window from kexec 'load' to kexec 'execute'. Update ima_add_kexec_buffer() function to allocate memory based on the Kconfig option value, rather than the currently hardcoded one. Signed-off-by: Tushar Sugandhi --- security/integrity/ima/Kconfig | 9 +++++++++ security/integrity/ima/ima_kexec.c | 13 ++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig index 60a511c6b583..8792b7aab768 100644 --- a/security/integrity/ima/Kconfig +++ b/security/integrity/ima/Kconfig @@ -338,3 +338,12 @@ config IMA_DISABLE_HTABLE default n help This option disables htable to allow measurement of duplicate records. + +config IMA_KEXEC_EXTRA_MEMORY_KB + int + depends on IMA && IMA_KEXEC + default 64 + help + IMA_KEXEC_EXTRA_MEMORY_KB determines the extra memory to be + allocated (in kb) for IMA measurements added in the window + from kexec 'load' to kexec 'execute'. diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c index 55bd5362262e..063da9c834a0 100644 --- a/security/integrity/ima/ima_kexec.c +++ b/security/integrity/ima/ima_kexec.c @@ -128,15 +128,18 @@ void ima_add_kexec_buffer(struct kimage *image) 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) + + (CONFIG_IMA_KEXEC_EXTRA_MEMORY_KB * 1024); + 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"); From patchwork Sat Dec 16 01:07:29 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 13495306 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 558061363 for ; Sat, 16 Dec 2023 01:07:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.microsoft.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b="cdQR0bvD" Received: from tushar-HP-Pavilion-Laptop-15-eg0xxx.lan (unknown [50.46.228.62]) by linux.microsoft.com (Postfix) with ESMTPSA id A6C6B20B3CC5; Fri, 15 Dec 2023 17:07:40 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com A6C6B20B3CC5 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1702688861; bh=VKCDyBNAtLzbD9bEYAgMrB8Tn92NT5hA4Th4n1dFxBE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cdQR0bvDJq65Ivx9V//Qq2WtnEIs6ohMgKh94PMilADBuAeUy8PdApbWOxODqIRFo rhD1z0Bd0D+qw2p+F7h9BB41F02JRpNm0mWcKJXPHUtJjFLFxAoC6VG/huAG1qQw7K /m+G5NRuwatrFtPtcDMeAskde90Y2UfxIBPkwNjM= From: Tushar Sugandhi To: zohar@linux.ibm.com, roberto.sassu@huaweicloud.com, roberto.sassu@huawei.com, eric.snowberg@oracle.com, stefanb@linux.ibm.com, ebiederm@xmission.com, noodles@fb.com, bauermann@kolabnow.com, linux-integrity@vger.kernel.org, kexec@lists.infradead.org Cc: code@tyhicks.com, nramas@linux.microsoft.com, paul@paul-moore.com Subject: [PATCH v3 7/7] ima: measure kexec load and exec events as critical data Date: Fri, 15 Dec 2023 17:07:29 -0800 Message-Id: <20231216010729.2904751-8-tusharsu@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231216010729.2904751-1-tusharsu@linux.microsoft.com> References: <20231216010729.2904751-1-tusharsu@linux.microsoft.com> Precedence: bulk X-Mailing-List: linux-integrity@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 There could be a potential mismatch between IMA measurements and TPM PCR quotes caused by the indeterminate interval between kexec 'load' and 'execute'. Memory allocated at kexec 'load' for IMA log buffer may run out. It can lead to missing events in the IMA log after a soft reboot to the new Kernel, resulting in TPM PCR quotes mismatch and remote attestation failures. Define two new IMA events, 'kexec_load' and 'kexec_execute', to be measured as critical data at kexec 'load' and 'execute' respectively. These events serve as markers in the IMA log to verify the IMA events are captured between kexec 'load' and 'execute' window. The presence of a 'kexec_load' event in between the last two 'boot_aggregate' events in the IMA log implies this is a kexec soft reboot, and not a cold-boot. And the absence of 'kexec_execute' event after kexec soft reboot implies missing events in that window which results in inconsistency with TPM PCR quotes, necessitating a cold boot for further successful remote attestation. Signed-off-by: Tushar Sugandhi --- security/integrity/ima/ima_kexec.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c index 063da9c834a0..47da41a66dcc 100644 --- a/security/integrity/ima/ima_kexec.c +++ b/security/integrity/ima/ima_kexec.c @@ -17,6 +17,8 @@ #include "ima.h" #ifdef CONFIG_IMA_KEXEC +#define IMA_KEXEC_EVENT_LEN 128 + struct seq_file ima_kexec_file; static void *ima_kexec_buffer; static size_t kexec_segment_size; @@ -33,6 +35,8 @@ void ima_free_kexec_file_buf(struct seq_file *sf) static int ima_alloc_kexec_file_buf(size_t segment_size) { + char ima_kexec_event[IMA_KEXEC_EVENT_LEN]; + /* * kexec 'load' may be called multiple times. * Free and realloc the buffer only if the segment_size is @@ -42,7 +46,7 @@ static int ima_alloc_kexec_file_buf(size_t segment_size) ima_kexec_file.size == segment_size && ima_kexec_file.read_pos == 0 && ima_kexec_file.count == sizeof(struct ima_kexec_hdr)) - return 0; + goto out; ima_free_kexec_file_buf(&ima_kexec_file); @@ -55,6 +59,13 @@ static int ima_alloc_kexec_file_buf(size_t segment_size) ima_kexec_file.read_pos = 0; ima_kexec_file.count = sizeof(struct ima_kexec_hdr); /* reserved space */ +out: + scnprintf(ima_kexec_event, IMA_KEXEC_EVENT_LEN, + "kexec_segment_size=%lu;", segment_size); + + ima_measure_critical_data("ima_kexec", "kexec_load", ima_kexec_event, + strlen(ima_kexec_event), false, NULL, 0); + return 0; } @@ -179,6 +190,7 @@ void ima_add_kexec_buffer(struct kimage *image) static int ima_update_kexec_buffer(struct notifier_block *self, unsigned long action, void *data) { + char ima_kexec_event[IMA_KEXEC_EVENT_LEN]; void *buf = NULL; size_t buf_size; bool resume = false; @@ -194,6 +206,15 @@ static int ima_update_kexec_buffer(struct notifier_block *self, return ret; } + buf_size = ima_get_binary_runtime_size(); + scnprintf(ima_kexec_event, IMA_KEXEC_EVENT_LEN, + "kexec_segment_size=%lu;ima_binary_runtime_size=%lu;", + kexec_segment_size, buf_size); + + ima_measure_critical_data("ima_kexec", "kexec_execute", + ima_kexec_event, strlen(ima_kexec_event), + false, NULL, 0); + ima_measurements_suspend(); ret = ima_dump_measurement_list(&buf_size, &buf,