@@ -1094,6 +1094,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
new file mode 100644
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2020 Microsoft Corporation
+ *
+ * Author: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
+ *
+ */
+#ifndef _ASM_ARCH_IMA_H
+#define _ASM_ARCH_IMA_H
+
+#include <linux/of.h>
+
+#ifdef CONFIG_IMA_KEXEC
+int setup_ima_buffer(const struct kimage *image, void *dtb, int off);
+#else
+static inline int setup_ima_buffer(const struct kimage *image, void *dtb,
+ int off)
+{
+ remove_ima_buffer(dtb, off);
+ return 0;
+}
+#endif /* CONFIG_IMA_KEXEC */
+
+#endif /* _ASM_ARCH_IMA_H */
@@ -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;
@@ -60,6 +60,7 @@ obj-$(CONFIG_ARM_SDE_INTERFACE) += sdei.o
obj-$(CONFIG_ARM64_PTR_AUTH) += pointer_auth.o
obj-$(CONFIG_SHADOW_CALL_STACK) += scs.o
obj-$(CONFIG_ARM64_MTE) += mte.o
+obj-$(CONFIG_IMA_KEXEC) += ima.o
obj-y += vdso/ probes/
obj-$(CONFIG_COMPAT_VDSO) += vdso32/
new file mode 100644
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2020 Microsoft Corporation
+ *
+ * Author: Lakshmi Ramasubramanian <nramas@linux.microsoft.com>
+ *
+ */
+
+#include <linux/kexec.h>
+#include <linux/of.h>
+#include <linux/libfdt.h>
+#include <asm/ima.h>
+
+/**
+ * setup_ima_buffer - add IMA buffer information to the fdt
+ *
+ * @image: kexec image being loaded.
+ * @dtb: Flattened device tree for the next kernel.
+ * @off: Offset to the chosen node.
+ *
+ * Return: 0 on success, or negative errno on error.
+ */
+int setup_ima_buffer(const struct kimage *image, void *dtb, int off)
+{
+ int ret = 0;
+
+ remove_ima_buffer(dtb, off);
+
+ /* add ima-kexec-buffer */
+ if (image->arch.ima_buffer_size > 0) {
+ ret = fdt_appendprop_addrrange(dtb, 0, off,
+ "linux,ima-kexec-buffer",
+ image->arch.ima_buffer_addr,
+ image->arch.ima_buffer_size);
+ if (ret) {
+ ret = (ret == -FDT_ERR_NOSPACE ? -ENOMEM : -EINVAL);
+ goto out;
+ }
+
+ ret = fdt_add_mem_rsv(dtb, image->arch.ima_buffer_addr,
+ image->arch.ima_buffer_size);
+ }
+
+out:
+ if (ret)
+ pr_err("Error setting up ima buffer in device tree.\n");
+
+ return ret;
+}
@@ -21,6 +21,7 @@
#include <linux/string.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
+#include <asm/ima.h>
const struct kexec_file_ops * const kexec_file_loaders[] = {
&kexec_image_ops,
@@ -83,6 +84,13 @@ static int create_dtb(struct kimage *image,
}
}
+ ret = setup_ima_buffer(image, buf,
+ fdt_path_offset(buf, "/chosen"));
+ if (ret) {
+ vfree(buf);
+ return ret;
+ }
+
/* trim it */
fdt_pack(buf);
*dtb = buf;