From: Tushar Sugandhi <tusharsu@linux.microsoft.com> 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 [thread overview] Message-ID: <20240122183804.3293904-3-tusharsu@linux.microsoft.com> (raw) In-Reply-To: <20240122183804.3293904-1-tusharsu@linux.microsoft.com> 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 <tusharsu@linux.microsoft.com> --- 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 */ /* -- 2.25.1 _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
WARNING: multiple messages have this Message-ID (diff)
From: Tushar Sugandhi <tusharsu@linux.microsoft.com> 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 [thread overview] Message-ID: <20240122183804.3293904-3-tusharsu@linux.microsoft.com> (raw) In-Reply-To: <20240122183804.3293904-1-tusharsu@linux.microsoft.com> 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 <tusharsu@linux.microsoft.com> --- 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 */ /* -- 2.25.1
next prev parent reply other threads:[~2024-01-22 18:38 UTC|newest] Thread overview: 52+ messages / expand[flat|nested] mbox.gz Atom feed top 2024-01-22 18:37 [PATCH v4 0/7] ima: kexec: measure events between kexec load and execute Tushar Sugandhi 2024-01-22 18:37 ` Tushar Sugandhi 2024-01-22 18:37 ` [PATCH v4 1/7] ima: define and call ima_alloc_kexec_file_buf Tushar Sugandhi 2024-01-22 18:37 ` Tushar Sugandhi 2024-01-24 2:54 ` Stefan Berger 2024-01-24 2:54 ` Stefan Berger 2024-01-24 3:38 ` Stefan Berger 2024-01-24 3:38 ` Stefan Berger 2024-01-26 22:14 ` Tushar Sugandhi 2024-01-26 22:14 ` Tushar Sugandhi 2024-01-24 13:33 ` Mimi Zohar 2024-01-24 13:33 ` Mimi Zohar 2024-01-25 19:03 ` Tushar Sugandhi 2024-01-25 19:03 ` Tushar Sugandhi 2024-01-22 18:37 ` Tushar Sugandhi [this message] 2024-01-22 18:37 ` [PATCH v4 2/7] kexec: define functions to map and unmap segments Tushar Sugandhi 2024-01-23 17:03 ` Stefan Berger 2024-01-23 17:03 ` Stefan Berger 2024-01-23 20:39 ` Tushar Sugandhi 2024-01-23 20:39 ` Tushar Sugandhi 2024-01-22 18:38 ` [PATCH v4 3/7] ima: kexec: skip IMA segment validation after kexec soft reboot Tushar Sugandhi 2024-01-22 18:38 ` Tushar Sugandhi 2024-01-22 18:38 ` [PATCH v4 4/7] ima: kexec: move ima log copy from kexec load to execute Tushar Sugandhi 2024-01-22 18:38 ` Tushar Sugandhi 2024-01-24 16:11 ` Mimi Zohar 2024-01-24 16:11 ` Mimi Zohar 2024-01-25 19:06 ` Tushar Sugandhi 2024-01-25 19:06 ` Tushar Sugandhi 2024-01-22 18:38 ` [PATCH v4 5/7] ima: suspend measurements during buffer copy at kexec execute Tushar Sugandhi 2024-01-22 18:38 ` Tushar Sugandhi 2024-01-23 18:18 ` Stefan Berger 2024-01-23 18:18 ` Stefan Berger 2024-01-23 20:55 ` Tushar Sugandhi 2024-01-23 20:55 ` Tushar Sugandhi 2024-01-22 18:38 ` [PATCH v4 6/7] ima: make the kexec extra memory configurable Tushar Sugandhi 2024-01-22 18:38 ` Tushar Sugandhi 2024-01-23 19:02 ` Stefan Berger 2024-01-23 19:02 ` Stefan Berger 2024-01-23 21:19 ` Tushar Sugandhi 2024-01-23 21:19 ` Tushar Sugandhi 2024-01-24 1:48 ` Stefan Berger 2024-01-24 1:48 ` Stefan Berger 2024-01-24 14:07 ` Mimi Zohar 2024-01-24 14:07 ` Mimi Zohar 2024-01-25 19:14 ` Tushar Sugandhi 2024-01-25 19:14 ` Tushar Sugandhi 2024-01-22 18:38 ` [PATCH v4 7/7] ima: measure kexec load and exec events as critical data Tushar Sugandhi 2024-01-22 18:38 ` Tushar Sugandhi 2024-01-24 14:35 ` Mimi Zohar 2024-01-24 14:35 ` Mimi Zohar 2024-01-25 19:16 ` Tushar Sugandhi 2024-01-25 19:16 ` Tushar Sugandhi
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20240122183804.3293904-3-tusharsu@linux.microsoft.com \ --to=tusharsu@linux.microsoft.com \ --cc=bauermann@kolabnow.com \ --cc=code@tyhicks.com \ --cc=ebiederm@xmission.com \ --cc=eric.snowberg@oracle.com \ --cc=kexec@lists.infradead.org \ --cc=linux-integrity@vger.kernel.org \ --cc=noodles@fb.com \ --cc=nramas@linux.microsoft.com \ --cc=paul@paul-moore.com \ --cc=roberto.sassu@huawei.com \ --cc=roberto.sassu@huaweicloud.com \ --cc=stefanb@linux.ibm.com \ --cc=zohar@linux.ibm.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.