From patchwork Mon Jan 22 18:37:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 13526055 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id C721754BD1 for ; Mon, 22 Jan 2024 18:38:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1705948697; cv=none; b=clK5dkl5vzBzWSanRJhMu37rh8vN5LkGiKMI1xHR/B6ZAeD/tnrIQLEBT0eckGUUzQk6/eOFZ+eXs4+IsI0LHiIDYUVidmTxOVYZHmIkH41CsMITM4qtw2Y4+zWBz0pxTT5uWJiGI8YO5rLe9U5DdUDkWnySb8hy8ghkVE1RJBg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1705948697; c=relaxed/simple; bh=rzlEfH4BH1sgznC/UhwvS8OYQKnfy6TxLTON8TxS9zE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=FarGRIzPqs0TPFR9MiE/xz7wjkWiQ9Cgi2ckN/I5zPEdtgJWqW9GCxR9KT8MprvI9ozF7qlb1irnyxgEBwmPvQf+KckwJF9nXHXEqbohXeSPk8MtYmLeQev+LW4NCaEI6eHVZN/IlbIxGQbp+VYSw7IsLEPrloQEdXT9roAF+v8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=Oe8BZj6h; arc=none smtp.client-ip=13.77.154.182 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="Oe8BZj6h" Received: from tushar-HP-Pavilion-Laptop-15-eg0xxx.lan (unknown [50.46.228.62]) by linux.microsoft.com (Postfix) with ESMTPSA id 4D11820E2C0A; Mon, 22 Jan 2024 10:38:15 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 4D11820E2C0A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1705948695; bh=qJHN560TUZe/5m2Gya0jv8CgnkhIqfBUCJMwNbKONAk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Oe8BZj6hMBvY5o1xChVYXTZ58hlM5FZ1WkPHd6CmU76c37WMkBJMuHaS6r1AlLa4E cFLEsSo4gkeJGI0Ozgo0IyGtqNMFy1xpsxKaTchsKKnFdZsYkusfDzyDrS6LrJ+tT+ AdBEZhp5IZCpFMI3NL4G6AYEiwc9FlQgxHENtYtA= 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 v4 1/7] ima: define and call ima_alloc_kexec_file_buf Date: Mon, 22 Jan 2024 10:37:58 -0800 Message-Id: <20240122183804.3293904-2-tusharsu@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240122183804.3293904-1-tusharsu@linux.microsoft.com> References: <20240122183804.3293904-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() which allocates buffer of size 'kexec_segment_size' at kexec 'load'. Make the local variable ima_kexec_file in function ima_dump_measurement_list() as local static to the file, so that it 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..99daac355c70 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 +static struct seq_file ima_kexec_file; + +static 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 Mon Jan 22 18:37:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 13526057 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id EDFB354BD2 for ; Mon, 22 Jan 2024 18:38:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1705948697; cv=none; b=hniObMcoliq2wm261tlnQ2HgqoDS0H2sX84WJrW3yZnPlpyLl+iacKgHhb+zFQWYfRTFZyvud6AvllTbPchl3RitH5xjkQQgIeYQaqjX1nCZx9PkSLntIbuRez4V9Guys0V4X5yNV+eDTHJBy25/TXY61m+OycNcNsuolEzjuN4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1705948697; c=relaxed/simple; bh=ZOrdno3y7/KMunBysKdCTRlJ8Eg0zvA6n9pFmmLI6Ds=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=OSYcqK3dfwD93sdJMBFmdWH10NISQNegvvBQogtpFR0yg9UEG7CYPBHsPxQlvuSVvqI90IS/OpZskGmV4Mw5PPWyaPTvNWGbR3gyiwIEn77DaTlwj9LW3yfs0uvR2/dBqcaS46fsS6EafO69OEtddU9SHnM99fqiJXzVlZAH6SE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=sLDas/Ov; arc=none smtp.client-ip=13.77.154.182 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="sLDas/Ov" Received: from tushar-HP-Pavilion-Laptop-15-eg0xxx.lan (unknown [50.46.228.62]) by linux.microsoft.com (Postfix) with ESMTPSA id 85C0820E2C12; Mon, 22 Jan 2024 10:38:15 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 85C0820E2C12 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1705948695; bh=FNPRDHEWO03k36za5OMYpzu6MavkRztENRokb7OKgbk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sLDas/Ovfnm56v//7NHkSDWoZJ69hjL6uEM6SJsU4X5gSthLlQZIIbpz0ZfZytvzU oU+ZugGE+l4DZ9whVrTD3op0jvIevRAy37vWT7y9CvvZlPR15nRa1WQdIo2aBdIQCe y65EJNTg8FKEJryPYJADJzpvR7MKTnnLMJaaelIQ= 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 v4 2/7] kexec: define functions to map and unmap segments Date: Mon, 22 Jan 2024 10:37:59 -0800 Message-Id: <20240122183804.3293904-3-tusharsu@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240122183804.3293904-1-tusharsu@linux.microsoft.com> References: <20240122183804.3293904-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. Implement kimage_unmap_segment() for unmapping segments using vunmap(). Relocate 'for_each_kimage_entry()' macro from kexec_core.c to kexec.h for broader accessibility. Signed-off-by: Tushar Sugandhi --- include/linux/kexec.h | 13 +++++++ kernel/kexec_core.c | 59 +++++++++++++++++++++++++++--- security/integrity/ima/ima_kexec.c | 1 + 3 files changed, 68 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..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 99daac355c70..4f944c9b4168 100644 --- a/security/integrity/ima/ima_kexec.c +++ b/security/integrity/ima/ima_kexec.c @@ -170,6 +170,7 @@ void ima_add_kexec_buffer(struct kimage *image) pr_debug("kexec measurement buffer for the loaded kernel at 0x%lx.\n", kbuf.mem); } + #endif /* IMA_KEXEC */ /* From patchwork Mon Jan 22 18:38:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 13526058 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 9419B54BD7 for ; Mon, 22 Jan 2024 18:38:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1705948697; cv=none; b=F5/COxuuRNSQZV8JXtwcMMu8ULrLAZNRn7pKiB7Qwm1l5glaj9ASCRwr0ztdGot3o3UQXGfejHGqhTu/R1a5Bm3MwQjlPi833Q7+RiLBOUwpN/Boxnvsah3jUmONfr2r0X82aXT/9Vk8DgClhDrjNJXH+fUMU6wwkWULzzVTy08= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1705948697; c=relaxed/simple; bh=pjaSgOhi28hwvS9Nv41rkItTCjY0iAwzcI9TfMOit1c=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=GnAry0ZS7RZlcTiDC6wuYDxTONtgBq87zBNtS3ExwiOLbYH0Vs4I+I3bgC6kRV/BPX+VZVws7AlY561abN5cqq5KjPsBtBGLggy4f+gracyq8igXrOMPPF7QvD0S/JuD72TBN3bgWOjg7o+U3JblbQV7+OwhiF/p6oKNIBzM2Jk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=ImRy9VmS; arc=none smtp.client-ip=13.77.154.182 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="ImRy9VmS" Received: from tushar-HP-Pavilion-Laptop-15-eg0xxx.lan (unknown [50.46.228.62]) by linux.microsoft.com (Postfix) with ESMTPSA id BCCAA20E2C18; Mon, 22 Jan 2024 10:38:15 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com BCCAA20E2C18 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1705948696; bh=06l468Ace46pgsOl3SC3DbsNNCIbYOZvyp2JfoJ3taA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ImRy9VmSeKD77UDZBXPJNgXD15itjsj9Lzk/8QXKlBQgXnD1twCCOBqWHvVA91oR3 Rlh6Pf2cCyWzP/qi1XwRc9GfQ1QGIUeVqGAurtLwfbfSbi13HWkpc49yuqpRgJscBB PnZCmP0sM190ITL46Cf/dEKgYkNuoNMNy9lDEVEk= 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 v4 3/7] ima: kexec: skip IMA segment validation after kexec soft reboot Date: Mon, 22 Jan 2024 10:38:00 -0800 Message-Id: <20240122183804.3293904-4-tusharsu@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240122183804.3293904-1-tusharsu@linux.microsoft.com> References: <20240122183804.3293904-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 kexec_calculate_store_digests() calculates and stores the digest of the segment at kexec_file_load syscall where the IMA segment is also allocated. With this series, the IMA segment will be updated with the measurement log at kexec soft reboot. Therefore, it may fail digest verification in verify_sha256_digest() after kexec soft reboot into the new Kernel. Skip IMA segment from calculating and storing digest in function kexec_calculate_store_digests() so that it is not added to the 'purgatory_sha_regions'. Since verify_sha256_digest() only verifies 'purgatory_sha_regions', no change is needed in verify_sha256_digest() in this context. With this change, the IMA segment is not included in the digest calculation, storage, and verification. Signed-off-by: Tushar Sugandhi --- include/linux/kexec.h | 3 +++ kernel/kexec_file.c | 8 ++++++++ security/integrity/ima/ima_kexec.c | 3 +++ 3 files changed, 14 insertions(+) diff --git a/include/linux/kexec.h b/include/linux/kexec.h index e00b8101b53b..eb98aca7f4c7 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_kexec.c b/security/integrity/ima/ima_kexec.c index 4f944c9b4168..d92a48284cc4 100644 --- a/security/integrity/ima/ima_kexec.c +++ b/security/integrity/ima/ima_kexec.c @@ -156,6 +156,7 @@ void ima_add_kexec_buffer(struct kimage *image) 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,6 +167,8 @@ 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); From patchwork Mon Jan 22 18:38:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 13526059 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id B70A354BD5 for ; Mon, 22 Jan 2024 18:38:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1705948698; cv=none; b=eOmarQjQZHMUHe8gJXZ5603TR2k63332ZcZtpt7kiXCAvo0fftcw7bMMPxq1i21ef11J2VsuhYzCZOh4VnLZKUCRF8J+/DiGDNRINeJ4GEWA0niJFclPIsoaqpa4RZ1YqhmuWLvJEfPOGdZ71L1FcyXLm4y4JViMVxJFEmuGfEY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1705948698; c=relaxed/simple; bh=nG78O/3l48VAm0hkSSg8G9IsDmxxMPEZCe8NeDkLU/Y=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=qtt55eTCXfaorywgoXuJgoxr11poo1JQk0o+IlCIUzhP8clwG1UjZG3jFhpC/vdYMD5XWUM/g+P3y2i3bWuE7VOszu7c7ocUQ3HWlLHuUzt7JvMeaYSCgRDxRBVuJ3+chQcxolgnTFdDsiR/q6EryxOjBdwH6Dks1pka5YeRnRI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=fA3/ssD3; arc=none smtp.client-ip=13.77.154.182 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="fA3/ssD3" Received: from tushar-HP-Pavilion-Laptop-15-eg0xxx.lan (unknown [50.46.228.62]) by linux.microsoft.com (Postfix) with ESMTPSA id 46E7920E2C1E; Mon, 22 Jan 2024 10:38:16 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 46E7920E2C1E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1705948696; bh=Vioe34zsK0dJO7/3HnBy+QyD5TmI5M0Zcz+q4dbfEKE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fA3/ssD3T7v37xzv8e6aMG/kyda4oALnVI+T8J2c4xdDWqHQeGgrV2Vg5E6kwoQ3F PvlOKaL4AABuV+Tk/Ail9HJ6eeBXYcvNqIA3wYIjPhfSIf87hrt70vAOxbjdYTmn5U q1btsjOEBV72BSUUruY2xVpHIkQwq1Qor7Q1zL3w= 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 v4 4/7] ima: kexec: move ima log copy from kexec load to execute Date: Mon, 22 Jan 2024 10:38:01 -0800 Message-Id: <20240122183804.3293904-5-tusharsu@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240122183804.3293904-1-tusharsu@linux.microsoft.com> References: <20240122183804.3293904-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 during kexec 'load', which may result in loss of IMA measurements during kexec soft reboot. It needs to be called during kexec 'execute'. The below changes need to be part of the same patch to ensure this patch series remains bisect-safe by ensuring the IMA log gets copied over during kexec soft reboot both before and after this patch. Implement ima_update_kexec_buffer() to be called during kexec 'execute'. Move ima_dump_measurement_list() from ima_add_kexec_buffer() to ima_update_kexec_buffer(). Make the necessary variables local static to the file, so that they are accessible during both kexec 'load' - where the memory is allocated and mapped to a segment in the new Kernel, and during 'execute' - where the IMA log gets copied over. Implement kimage_file_post_load() and ima_kexec_post_load() to be invoked after the new Kernel image has been loaded for kexec. ima_kexec_post_load() will map the IMA buffer to a segment in the newly loaded Kernel. It will also register the reboot notifier_block to trigger ima_update_kexec_buffer() at exec 'execute'. Modify kexec_file_load() syscall to call kimage_file_post_load() after the image has been loaded and prepared for kexec. Call it only on kexec soft reboot and not for KEXEC_FILE_ON_CRASH. Signed-off-by: Tushar Sugandhi --- include/linux/ima.h | 3 ++ kernel/kexec_file.c | 8 +++ security/integrity/ima/ima_kexec.c | 82 ++++++++++++++++++++++++++---- 3 files changed, 84 insertions(+), 9 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/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; diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c index d92a48284cc4..25150bfc7129 100644 --- a/security/integrity/ima/ima_kexec.c +++ b/security/integrity/ima/ima_kexec.c @@ -12,10 +12,15 @@ #include #include #include +#include +#include #include "ima.h" #ifdef CONFIG_IMA_KEXEC static struct seq_file ima_kexec_file; +static void *ima_kexec_buffer; +static size_t kexec_segment_size; +static bool ima_kexec_update_registered; static void ima_free_kexec_file_buf(struct seq_file *sf) { @@ -120,7 +125,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,14 +149,6 @@ 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; @@ -174,6 +170,74 @@ void ima_add_kexec_buffer(struct kimage *image) 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; + 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; + } + + ret = ima_dump_measurement_list(&buf_size, &buf, + kexec_segment_size); + + if (!buf) { + pr_err("%s: Dump measurements failed. Error:%d\n", + __func__, ret); + goto out; + } + memcpy(ima_kexec_buffer, buf, buf_size); +out: + kimage_unmap_segment(ima_kexec_buffer); + ima_kexec_buffer = NULL; + + return ret; +} + +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 Jan 22 18:38:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 13526060 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 720CE54BD1 for ; Mon, 22 Jan 2024 18:38:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1705948698; cv=none; b=ulZsEqK7ou+zRWmnbuTQRMK567yKj+o6n7vKgSlwy2+FUq42/MazEBav0VnNieIwbUDRpzpi9Cid7gBcaAifQNPEXBPpWIObbHh6/jQfH3puC2eJCaxOmAe0xiza+MLWISnVEfsDy6QvDRZnhWIltXYIrz7dRwQPt2OAr3LYiA0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1705948698; c=relaxed/simple; bh=Ypx1KqcnNL9TBY6xsnHX82qhp3DgxuMqMTuQWHjEJJM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Cu9ygVMf5DWqMJibIMoitm65UfdI2n0/ehLMbBFRfAYF47rd4GuEmT175gJQcBlI/9yfK3/+sul8gLxQ7mwcz9AcqUvaReIwf9WCp1O5RHE4zioUWiqBqfXXK9D9FSBzUAAeVSDV3fTiK0CEotEI2Lsikea++EUegxzCOOe2vpU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=q3VcWS6y; arc=none smtp.client-ip=13.77.154.182 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="q3VcWS6y" Received: from tushar-HP-Pavilion-Laptop-15-eg0xxx.lan (unknown [50.46.228.62]) by linux.microsoft.com (Postfix) with ESMTPSA id 7DB9A20E2C23; Mon, 22 Jan 2024 10:38:16 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 7DB9A20E2C23 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1705948696; bh=OrBlj8d920TOWK01B2VDtnxiB7Uu+7TUArXhXB9LNGk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=q3VcWS6yUWlRnjQuwObIpI7/TXFMUQN4ERhOE0qyDlARWTZEHRZRgWdbS8XtvGGwk 6ulCgUC77e0Gw5JMHtzxGjP/IhGxzSMx/uO7QLMzLSbMy84DJ0TksHKUwLj6aBZRMx cX9+N1KJlAjCDJ65z0YZw/+sU+rwjW0fFrcslAcA= 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 v4 5/7] ima: suspend measurements during buffer copy at kexec execute Date: Mon, 22 Jan 2024 10:38:02 -0800 Message-Id: <20240122183804.3293904-6-tusharsu@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240122183804.3293904-1-tusharsu@linux.microsoft.com> References: <20240122183804.3293904-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 New measurements added to the IMA log while the log is being copied during the kexec 'execute' may not get copied over. This can cause the measurement log to be out of sync with the IMA TPM PCR, which could result in breaking the integrity of the measurements after kexec soft reboot. Implement and call the functions ima_measurements_suspend() and ima_measurements_resume() from ima_update_kexec_buffer(). Add a check in the ima_add_template_entry() function not to measure events when 'suspend_ima_measurements' flag is set. This ensures the integrity of the IMA log while it is being copied over to the new Kernel during kexec 'execute'. Signed-off-by: Tushar Sugandhi Reviewed-by: Stefan Berger --- security/integrity/ima/ima.h | 2 ++ security/integrity/ima/ima_kexec.c | 7 +++++++ security/integrity/ima/ima_queue.c | 32 ++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+) 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 25150bfc7129..f26b5b342d84 100644 --- a/security/integrity/ima/ima_kexec.c +++ b/security/integrity/ima/ima_kexec.c @@ -179,6 +179,7 @@ static int ima_update_kexec_buffer(struct notifier_block *self, void *buf = NULL; size_t buf_size; int ret = NOTIFY_OK; + bool resume = false; if (!kexec_in_progress) { pr_info("%s: No kexec in progress.\n", __func__); @@ -190,12 +191,15 @@ static int ima_update_kexec_buffer(struct notifier_block *self, 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); @@ -203,6 +207,9 @@ static int ima_update_kexec_buffer(struct notifier_block *self, kimage_unmap_segment(ima_kexec_buffer); ima_kexec_buffer = NULL; + if (resume) + ima_measurements_resume(); + return ret; } diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c index 532da87ce519..5946a26a2849 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. @@ -176,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 Jan 22 18:38:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 13526061 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 8D7B254BF8 for ; Mon, 22 Jan 2024 18:38:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1705948698; cv=none; b=sKt0Bjg35qNGzqRLpBB+Rg7ZoTN+gTRtqr9qFso1i1EgVILWNH0Y9y1K35nB30VI5ZrbpSAXF8FZZa2xAaFOX5sZ9Lfk+P1rQnlxJC+UucAWA4BHrtibC1pEELYhg4xJ9/+t9XujM51/8ltSRtMWW4SnRqH+wzmGKWZvG2c32AM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1705948698; c=relaxed/simple; bh=91c+43s4KhCEe2Xk8isUeIzI/isagYKoWF4C1zvSgEg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=F968Aw2VurDJRfuz2iDXn13Q6QAHy3MRF9xSkp8XcP6a5GalEAP9IeJMf4xHZBh2rSR+dJ8Lnyo14i2/WOJYZ6VeMqAV0oBO39NJkkAUJa7PNzF0KdjQiiSCncMS6Rp95QPAkN5EXm6ZV3FsBMGPAXcXjZccUqEXvvgrfvSSeQo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=o7pEkKmy; arc=none smtp.client-ip=13.77.154.182 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="o7pEkKmy" Received: from tushar-HP-Pavilion-Laptop-15-eg0xxx.lan (unknown [50.46.228.62]) by linux.microsoft.com (Postfix) with ESMTPSA id E763B20E2C27; Mon, 22 Jan 2024 10:38:16 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com E763B20E2C27 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1705948697; bh=qWdS8NNgz0MGlGCMbGxri5f+7iqORqYYJwxxs6oaIek=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=o7pEkKmywyPkVQDCSStuFKrnTzeK2SvA6C4NRv28+Fiyhp1DdB5EeAgvp/HKaC1rO PHfMIVtmjKQ2YOq5SCZ22bpbjNCTUEfZNUunNpGa7k/MedP+iYrJ0CdHWF9Qm3RYue NKEN4EwgVWfbr8kaG9RTLrlke8RutyqojgTtTIEA= 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 v4 6/7] ima: make the kexec extra memory configurable Date: Mon, 22 Jan 2024 10:38:03 -0800 Message-Id: <20240122183804.3293904-7-tusharsu@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240122183804.3293904-1-tusharsu@linux.microsoft.com> References: <20240122183804.3293904-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 The extra memory allocated for carrying the IMA measurement list across kexec is hardcoded as half a PAGE. Make it configurable. Define a Kconfig option, IMA_KEXEC_EXTRA_MEMORY_KB, to configure the extra memory (in kb) to be allocated for IMA measurements added during kexec soft reboot. Ensure the default value of the option is set such that extra half a page of memory for additional measurements is allocated to maintain backwards compatibility. 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 | 11 +++++++++++ security/integrity/ima/ima_kexec.c | 15 ++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig index 60a511c6b583..fc103288852b 100644 --- a/security/integrity/ima/Kconfig +++ b/security/integrity/ima/Kconfig @@ -338,3 +338,14 @@ 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 0 + help + IMA_KEXEC_EXTRA_MEMORY_KB determines the extra memory to be + allocated (in kb) for IMA measurements added during kexec soft reboot. + If set to the default value, an extra half page of memory for + additional measurements will be allocated to maintain backwards + compatibility. diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c index f26b5b342d84..c126aa6494e9 100644 --- a/security/integrity/ima/ima_kexec.c +++ b/security/integrity/ima/ima_kexec.c @@ -121,6 +121,7 @@ void ima_add_kexec_buffer(struct kimage *image) .buf_min = 0, .buf_max = ULONG_MAX, .top_down = true }; unsigned long binary_runtime_size; + unsigned long extra_size; /* use more understandable variable names than defined in kbuf */ void *kexec_buffer = NULL; @@ -128,15 +129,19 @@ 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 during kexec. */ - binary_runtime_size = ima_get_binary_runtime_size(); + if (CONFIG_IMA_KEXEC_EXTRA_MEMORY_KB <= 0) + extra_size = PAGE_SIZE / 2; + else + extra_size = CONFIG_IMA_KEXEC_EXTRA_MEMORY_KB * 1024; + binary_runtime_size = ima_get_binary_runtime_size() + 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"); From patchwork Mon Jan 22 18:38:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tushar Sugandhi X-Patchwork-Id: 13526062 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 00FF41EEE6 for ; Mon, 22 Jan 2024 18:38:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=13.77.154.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1705948699; cv=none; b=cTvYYDHnmfs1G9vB9gKS/RMmrzWCYi2wbXrY5PS6VNuzq/3XuuoKQ0SkzVKu26mGNyRQ7ADRbAiRMXZZ6XjIapgssQagbCTx4q/6Mfmjc6CWoBZzIvn0MTMnITlc4wOWjZE3BxkeoNaWqxAlIsi8qUt0ats4WA6V/H50IXjxl9k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1705948699; c=relaxed/simple; bh=1n1MKNgcuPRuU7/9FcH1bapvw/KyXKCCKQ04Iq1awwE=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=JVBr1nqUtRjbEDy6p7HMUrIDVNYyPEBohOcTZcdR4hZpxZ7/VDL9AWEZXDcz5DxaGR2X3hleauKQLH/00u06/bUvruLjtB59IUvBJSbb1iv1Cjrr/YjQbSKdzZyZ/m7NTOkTQkvfnLwOZgGAZhwvAk3/nBkBnv2dqXRXPKzkp1M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.microsoft.com; spf=pass smtp.mailfrom=linux.microsoft.com; dkim=pass (1024-bit key) header.d=linux.microsoft.com header.i=@linux.microsoft.com header.b=i6bZdDnO; arc=none smtp.client-ip=13.77.154.182 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="i6bZdDnO" Received: from tushar-HP-Pavilion-Laptop-15-eg0xxx.lan (unknown [50.46.228.62]) by linux.microsoft.com (Postfix) with ESMTPSA id 5ECEE20E2C2D; Mon, 22 Jan 2024 10:38:17 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com 5ECEE20E2C2D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1705948697; bh=5BIJyIqOWqL1PpqhjQ9R7fLK9sgsyoZbpX8td5qK1ok=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=i6bZdDnOIAkXP/YVHYOVijxEWyMpuiKNZGcrV4nQgSHoDzDLAEEFjASjVM+/TtNao I8jH2mM41aTPrIAF1Arf+sKUUjlLr2qfzsBRQ8KlrUNUrWG/zKuPnOUuN+Euj1P8Sp 0tu8a2epnV4WJ6K4gdbWkEl78ESP1/Mqws4VRSZw= 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 v4 7/7] ima: measure kexec load and exec events as critical data Date: Mon, 22 Jan 2024 10:38:04 -0800 Message-Id: <20240122183804.3293904-8-tusharsu@linux.microsoft.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240122183804.3293904-1-tusharsu@linux.microsoft.com> References: <20240122183804.3293904-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'. The extra 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. Report the allocated kexec segment size, IMA binary log size and the runtime measurements count as part of those events. These events, and the values reported through them, serve as markers in the IMA log to verify the IMA events are captured during kexec soft reboot. 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 a successful remote attestation. Signed-off-by: Tushar Sugandhi --- security/integrity/ima/ima_kexec.c | 34 +++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c index c126aa6494e9..1f8b697f4ed0 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 + static struct seq_file ima_kexec_file; static void *ima_kexec_buffer; static size_t kexec_segment_size; @@ -33,6 +35,10 @@ static 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]; + size_t buf_size; + long len; + /* * kexec 'load' may be called multiple times. * Free and realloc the buffer only if the segment_size is @@ -42,7 +48,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 +61,18 @@ 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: + buf_size = ima_get_binary_runtime_size(); + len = atomic_long_read(&ima_htable.len); + + scnprintf(ima_kexec_event, IMA_KEXEC_EVENT_LEN, + "kexec_segment_size=%lu;ima_binary_runtime_size=%lu;" + "ima_runtime_measurements_count=%ld;", + segment_size, buf_size, len); + + ima_measure_critical_data("ima_kexec", "kexec_load", ima_kexec_event, + strlen(ima_kexec_event), false, NULL, 0); + return 0; } @@ -181,10 +199,12 @@ 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; int ret = NOTIFY_OK; bool resume = false; + long len; if (!kexec_in_progress) { pr_info("%s: No kexec in progress.\n", __func__); @@ -196,6 +216,18 @@ static int ima_update_kexec_buffer(struct notifier_block *self, return ret; } + buf_size = ima_get_binary_runtime_size(); + len = atomic_long_read(&ima_htable.len); + + scnprintf(ima_kexec_event, IMA_KEXEC_EVENT_LEN, + "kexec_segment_size=%lu;ima_binary_runtime_size=%lu;" + "ima_runtime_measurements_count=%ld;", + kexec_segment_size, buf_size, len); + + 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,