Add support for using reserved memory for ima buffer pass
Subsystems (7)
cover Add support for using reserved memory for ima buffer pass
IMA during kexec(kexec file load) verifies the kernel signature and measures the signature of the kernel. The signature in the logs can be used to verfiy the authenticity of the kernel. The logs don not get carried over kexec and thus remote attesation cannot verify the signature of the running kernel.
Introduce an ABI to carry forward the ima logs over kexec. Memory reserved via device tree reservation can be used to store and read via the of_* functions.
Reserved memory stores the size(sizeof(size_t)) of the buffer in the starting address, followed by the IMA log contents.
Tested on:
arm64 with Uboot
Prakhar Srivastava (2):
Add a layer of abstraction to use the memory reserved by device tree
for ima buffer pass.
Add support for ima buffer pass using reserved memory for arm64 kexec.
Update the arch sepcific code path in kexec file load to store the ima buffer in the reserved memory. The same reserved memory is read on kexec or cold boot.
arch/arm64/Kconfig | 1 + arch/arm64/include/asm/ima.h | 22 ++++ arch/arm64/include/asm/kexec.h | 5 + arch/arm64/kernel/Makefile | 1 + arch/arm64/kernel/ima_kexec.c | 64 ++++++++++ arch/arm64/kernel/machine_kexec_file.c | 1 + arch/powerpc/include/asm/ima.h | 3 +- arch/powerpc/kexec/ima.c | 14 ++- drivers/of/Kconfig | 6 + drivers/of/Makefile | 1 + drivers/of/of_ima.c | 165 +++++++++++++++++++++++++ include/linux/of.h | 34 +++++ security/integrity/ima/ima_kexec.c | 15 ++- 13 files changed, 325 insertions(+), 7 deletions(-) create mode 100644 arch/arm64/include/asm/ima.h create mode 100644 arch/arm64/kernel/ima_kexec.c create mode 100644 drivers/of/of_ima.c
Signature · 1 line
2.25.1
RFC 1/1 {PATCH 1/2] Add a layer of abstraction to use the memory reserved by device tree for ima buffer pass.
Introduce a device tree layer for to read and store ima buffer from the reserved memory section of a device tree.
--- drivers/of/Kconfig | 6 ++ drivers/of/Makefile | 1 + drivers/of/of_ima.c | 165 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/of.h | 34 +++++++++ 4 files changed, 206 insertions(+) create mode 100644 drivers/of/of_ima.c
drivers/of/Kconfig +6 -0
@@ -107,4 +107,10 @@ config OF_DMA_DEFAULT_COHERENT # arches should select this if DMA is coherent by default for OF devices bool +config OF_IMA + def_bool y + help + IMA related wrapper functions to add/remove ima measurement logs during + kexec_file_load call. + endif # OF
drivers/of/Makefile +1 -0
@@ -14,5 +14,6 @@ obj-$(CONFIG_OF_RESERVED_MEM) += of_reserved_mem.o obj-$(CONFIG_OF_RESOLVE) += resolver.o obj-$(CONFIG_OF_OVERLAY) += overlay.o obj-$(CONFIG_OF_NUMA) += of_numa.o +obj-$(CONFIG_OF_IMA) += of_ima.o obj-$(CONFIG_OF_UNITTEST) += unittest-data/
drivers/of/of_ima.c new file +165 -0
165 lines not on this page · raw message
include/linux/of.h +34 -0
@@ -1485,4 +1485,38 @@ static inline int of_overlay_notifier_unregister(struct notifier_block *nb)#endif +#ifdef CONFIG_OF_IMA +int of_is_ima_memory_reserved (void ); +int of_remove_ima_buffer (void ); +int of_get_ima_buffer (void **addr,size_t *size); +size_t of_ima_get_size_allocated (void ); +int of_ima_write_buffer (void *ima_buffer, +size_t ima_buffer_size); +#else +static inline int of_is_ima_memory_reserved (void ) +{ +return -ENOTSUPP ; +}; +static inline int of_remove_ima_buffer (void ) +{ +return -ENOTSUPP ; +}; + +static inline int of_get_ima_buffer (void **addr,size_t *size) +{ +return -ENOTSUPP ; +}; + +static inline size_t of_ima_get_size_allocated (void ) +{ +return 0 ; +}; + +static inline int of_ima_write_buffer (void *ima_buffer, +size_t ima_buffer_size) +{ +return -ENOTSUPP ; +}; +#endif +#endif /* _LINUX_OF_H */
Signature · 1 line
2.25.1
RFC PATCH 2/2 Add support for ima buffer pass using reserved memory arm64
In reply to Prakhar Srivastava Add support for ima buffer pass using reserved memory for
arm64 kexec. Update the arch sepcific code path in kexec file load to store the ima buffer in the reserved memory. The same reserved memory is read on kexec or cold boot.
--- arch/arm64/Kconfig | 1 + arch/arm64/include/asm/ima.h | 22 +++++++++ arch/arm64/include/asm/kexec.h | 5 ++ arch/arm64/kernel/Makefile | 1 + arch/arm64/kernel/ima_kexec.c | 64 ++++++++++++++++++++++++++ arch/arm64/kernel/machine_kexec_file.c | 1 + arch/powerpc/include/asm/ima.h | 3 +- arch/powerpc/kexec/ima.c | 14 +++++- security/integrity/ima/ima_kexec.c | 15 ++++-- 9 files changed, 119 insertions(+), 7 deletions(-) create mode 100644 arch/arm64/include/asm/ima.h create mode 100644 arch/arm64/kernel/ima_kexec.c
arch/arm64/Kconfig +1 -0
@@ -1069,6 +1069,7 @@ config KEXEC config KEXEC_FILE bool "kexec file based system call" select KEXEC_CORE + select HAVE_IMA_KEXEC help This is new version of kexec system call. This system call is file based and takes file descriptors as system call argument
arch/arm64/include/asm/ima.h new file +22 -0
@@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_ARM64_IMA_H +#define _ASM_ARM64_IMA_H + +struct kimage ; + +int is_ima_memory_reserved (void ); +int ima_get_kexec_buffer (void **addr,size_t *size); +int ima_free_kexec_buffer (void ); + +#ifdef CONFIG_IMA_KEXEC +int arch_ima_add_kexec_buffer (struct kimage *image,unsigned long load_addr, +void *buffer,size_t size); + +#else +int arch_ima_add_kexec_buffer (struct kimage *image,unsigned long load_addr, +void *buffer,size_t size) +{ +return 0 ; +} +#endif /* CONFIG_IMA_KEXEC */ +#endif /* _ASM_ARM64_IMA_H */
arch/arm64/include/asm/kexec.h +5 -0
@@ -100,6 +100,11 @@ struct kimage_arch {void *elf_headers;unsigned long elf_headers_mem;unsigned long elf_headers_sz; + +#ifdef CONFIG_IMA_KEXEC +phys_addr_t ima_buffer_addr; +size_t ima_buffer_size; +#endif };extern const struct kexec_file_ops kexec_image_ops;
arch/arm64/kernel/Makefile +1 -0
@@ -55,6 +55,7 @@ obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o obj-$(CONFIG_HIBERNATION) += hibernate.o hibernate-asm.o obj-$(CONFIG_KEXEC_CORE) += machine_kexec.o relocate_kernel.o \ cpu-reset.o +obj-$(CONFIG_HAVE_IMA_KEXEC) += ima_kexec.o obj-$(CONFIG_KEXEC_FILE) += machine_kexec_file.o kexec_image.o obj-$(CONFIG_ARM64_RELOC_TEST) += arm64-reloc-test.o arm64-reloc-test-y := reloc_test_core.o reloc_test_syms.o
arch/arm64/kernel/ima_kexec.c new file +64 -0
64 lines not on this page · raw message
arch/arm64/kernel/machine_kexec_file.c +1 -0
@@ -22,6 +22,7 @@#include <linux/types.h> #include <linux/vmalloc.h> #include <asm/byteorder.h> +#include <asm/ima.h> /* relevant device tree properties */ #define FDT_PROP_KEXEC_ELFHDR "linux,elfcorehdr"
arch/powerpc/include/asm/ima.h +2 -1
@@ -4,6 +4,7 @@struct kimage ; +int is_ima_memory_reserved (void );int ima_get_kexec_buffer (void **addr,size_t *size);int ima_free_kexec_buffer (void );
@@ -15,7 +16,7 @@ static inline void remove_ima_buffer(void *fdt, int chosen_node) {}#ifdef CONFIG_IMA_KEXEC int arch_ima_add_kexec_buffer (struct kimage *image,unsigned long load_addr, -size_t size); +void *buffer,size_t size);int setup_ima_buffer (const struct kimage *image,void *fdt,int chosen_node);#else
arch/powerpc/kexec/ima.c +13 -1
@@ -46,6 +46,18 @@ static int do_get_kexec_buffer(const void *prop, int len, unsigned long *addr,return 0 ; } +/** +* is_ima_memory_reserved - check if memory is reserved via device +* tree. +* Return: negative or zero when memory is not reserved. +* positive number on success. +* +*/ +int is_ima_memory_reserved (void ) +{ +return -EOPNOTSUPP ; +} +/** * ima_get_kexec_buffer - get IMA buffer from the previous kernel * @addr: On successful return, set to point to the buffer contents.
@@ -137,7 +149,7 @@ void remove_ima_buffer(void *fdt, int chosen_node)* Return: 0 on success, negative errno on error. */ int arch_ima_add_kexec_buffer (struct kimage *image,unsigned long load_addr, -size_t size) +void *buffer,size_t size) { image->arch.ima_buffer_addr = load_addr; image->arch.ima_buffer_size = size;
security/integrity/ima/ima_kexec.c +10 -5
@@ -116,13 +116,18 @@ void ima_add_kexec_buffer(struct kimage *image) kbuf.buffer = kexec_buffer; kbuf.bufsz = kexec_buffer_size; kbuf.memsz = kexec_segment_size; - ret =kexec_add_buffer (&kbuf); -if (ret) { -pr_err ("Error passing over kexec measurement buffer.\n" ); -return ; + +if (!is_ima_memory_reserved ()) { + + ret =kexec_add_buffer (&kbuf); +if (ret) { +pr_err ("Error passing over kexec measurement buffer.\n" ); +return ; + } } - ret =arch_ima_add_kexec_buffer (image, kbuf.mem, kexec_segment_size); + ret =arch_ima_add_kexec_buffer (image, kbuf.mem, kexec_buffer, + kexec_segment_size);if (ret) {pr_err ("Error passing over kexec measurement buffer.\n" );return ;
Signature · 1 line
2.25.1