powerpc: Move ima buffer fields to struct kimage

The fields ima_buffer_addr and ima_buffer_size in "struct kimage_arch"
for powerpc are used to carry forward the IMA measurement list across
kexec system call.  These fields are not architecture specific, but are
currently limited to powerpc.

arch_ima_add_kexec_buffer() defined in "arch/powerpc/kexec/ima.c"
sets ima_buffer_addr and ima_buffer_size for the kexec system call.
This function does not have architecture specific code, but is
currently limited to powerpc.

Move ima_buffer_addr and ima_buffer_size to "struct kimage".
Set ima_buffer_addr and ima_buffer_size in ima_add_kexec_buffer()
in security/integrity/ima/ima_kexec.c.

Co-developed-by: Prakhar Srivastava <prsriva@linux.microsoft.com>
Signed-off-by: Prakhar Srivastava <prsriva@linux.microsoft.com>
Signed-off-by: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
Suggested-by: Will Deacon <will@kernel.org>
Reviewed-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>
Signed-off-by: Rob Herring <robh@kernel.org>
Link: https://lore.kernel.org/r/20210221174930.27324-9-nramas@linux.microsoft.com
This commit is contained in:
Lakshmi Ramasubramanian 2021-02-21 09:49:25 -08:00 committed by Rob Herring
parent 3c985d31ad
commit 0c605158be
5 changed files with 11 additions and 37 deletions

View File

@ -14,9 +14,6 @@ static inline void remove_ima_buffer(void *fdt, int chosen_node) {}
#endif #endif
#ifdef CONFIG_IMA_KEXEC #ifdef CONFIG_IMA_KEXEC
int arch_ima_add_kexec_buffer(struct kimage *image, unsigned long load_addr,
size_t size);
int setup_ima_buffer(const struct kimage *image, void *fdt, int chosen_node); int setup_ima_buffer(const struct kimage *image, void *fdt, int chosen_node);
#else #else
static inline int setup_ima_buffer(const struct kimage *image, void *fdt, static inline int setup_ima_buffer(const struct kimage *image, void *fdt,

View File

@ -108,11 +108,6 @@ struct kimage_arch {
unsigned long backup_start; unsigned long backup_start;
void *backup_buf; void *backup_buf;
void *fdt; void *fdt;
#ifdef CONFIG_IMA_KEXEC
phys_addr_t ima_buffer_addr;
size_t ima_buffer_size;
#endif
}; };
char *setup_kdump_cmdline(struct kimage *image, char *cmdline, char *setup_kdump_cmdline(struct kimage *image, char *cmdline,

View File

@ -128,23 +128,6 @@ void remove_ima_buffer(void *fdt, int chosen_node)
} }
#ifdef CONFIG_IMA_KEXEC #ifdef CONFIG_IMA_KEXEC
/**
* arch_ima_add_kexec_buffer - do arch-specific steps to add the IMA buffer
*
* Architectures should use this function to pass on the IMA buffer
* information to the next kernel.
*
* Return: 0 on success, negative errno on error.
*/
int arch_ima_add_kexec_buffer(struct kimage *image, unsigned long load_addr,
size_t size)
{
image->arch.ima_buffer_addr = load_addr;
image->arch.ima_buffer_size = size;
return 0;
}
static int write_number(void *p, u64 value, int cells) static int write_number(void *p, u64 value, int cells)
{ {
if (cells == 1) { if (cells == 1) {
@ -180,7 +163,7 @@ int setup_ima_buffer(const struct kimage *image, void *fdt, int chosen_node)
u8 value[16]; u8 value[16];
remove_ima_buffer(fdt, chosen_node); remove_ima_buffer(fdt, chosen_node);
if (!image->arch.ima_buffer_size) if (!image->ima_buffer_size)
return 0; return 0;
ret = get_addr_size_cells(&addr_cells, &size_cells); ret = get_addr_size_cells(&addr_cells, &size_cells);
@ -192,11 +175,11 @@ int setup_ima_buffer(const struct kimage *image, void *fdt, int chosen_node)
if (entry_size > sizeof(value)) if (entry_size > sizeof(value))
return -EINVAL; return -EINVAL;
ret = write_number(value, image->arch.ima_buffer_addr, addr_cells); ret = write_number(value, image->ima_buffer_addr, addr_cells);
if (ret) if (ret)
return ret; return ret;
ret = write_number(value + 4 * addr_cells, image->arch.ima_buffer_size, ret = write_number(value + 4 * addr_cells, image->ima_buffer_size,
size_cells); size_cells);
if (ret) if (ret)
return ret; return ret;
@ -206,13 +189,13 @@ int setup_ima_buffer(const struct kimage *image, void *fdt, int chosen_node)
if (ret < 0) if (ret < 0)
return -EINVAL; return -EINVAL;
ret = fdt_add_mem_rsv(fdt, image->arch.ima_buffer_addr, ret = fdt_add_mem_rsv(fdt, image->ima_buffer_addr,
image->arch.ima_buffer_size); image->ima_buffer_size);
if (ret) if (ret)
return -EINVAL; return -EINVAL;
pr_debug("IMA buffer at 0x%llx, size = 0x%zx\n", pr_debug("IMA buffer at 0x%llx, size = 0x%zx\n",
image->arch.ima_buffer_addr, image->arch.ima_buffer_size); image->ima_buffer_addr, image->ima_buffer_size);
return 0; return 0;
} }

View File

@ -304,6 +304,9 @@ struct kimage {
#ifdef CONFIG_IMA_KEXEC #ifdef CONFIG_IMA_KEXEC
/* Virtual address of IMA measurement buffer for kexec syscall */ /* Virtual address of IMA measurement buffer for kexec syscall */
void *ima_buffer; void *ima_buffer;
phys_addr_t ima_buffer_addr;
size_t ima_buffer_size;
#endif #endif
/* Core ELF header buffer */ /* Core ELF header buffer */

View File

@ -123,12 +123,8 @@ void ima_add_kexec_buffer(struct kimage *image)
return; return;
} }
ret = arch_ima_add_kexec_buffer(image, kbuf.mem, kexec_segment_size); image->ima_buffer_addr = kbuf.mem;
if (ret) { image->ima_buffer_size = kexec_segment_size;
pr_err("Error passing over kexec measurement buffer.\n");
return;
}
image->ima_buffer = kexec_buffer; image->ima_buffer = kexec_buffer;
pr_debug("kexec measurement buffer for the loaded kernel at 0x%lx.\n", pr_debug("kexec measurement buffer for the loaded kernel at 0x%lx.\n",