**Problem** In the arm64 case, a temporary file for kernel is created in pez_arm64_probe() and passed down to info.kernel_fd later. However in the x86_64 case, nobody passes a temporary fd to info.kernel_fd, so finally the fd of the UKI image is passed to syscall. That is not the expected behavior. **Situation** The current framework of kexec-tools passes kernel fd to syscall. Meanwhile info.kernel_fd presents each probe with an opportunity to overwhelm the existing kernel fd. **Solution** In the UKI probe, a temporary file is created to hold the .linux section. Later, if no other probe methods set info.kernel_fd, it will be set in the UKI load method. This way, the correct fd can be passed to the syscall. Signed-off-by: Pingfan Liu <piliu@xxxxxxxxxx> Cc: Simon Horman <horms@xxxxxxxxxx> To: kexec@xxxxxxxxxxxxxxxxxxx --- kexec/arch/arm64/kexec-vmlinuz-arm64.c | 2 ++ kexec/kexec-uki.c | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/kexec/arch/arm64/kexec-vmlinuz-arm64.c b/kexec/arch/arm64/kexec-vmlinuz-arm64.c index e291a34..e558296 100644 --- a/kexec/arch/arm64/kexec-vmlinuz-arm64.c +++ b/kexec/arch/arm64/kexec-vmlinuz-arm64.c @@ -104,6 +104,8 @@ int pez_arm64_load(int argc, char **argv, const char *buf, off_t len, off_t nread; int fd; + if (info->kernel_fd > 0) + close(info->kernel_fd); info->kernel_fd = kernel_fd; fd = dup(kernel_fd); if (fd < 0) { diff --git a/kexec/kexec-uki.c b/kexec/kexec-uki.c index 8a7d349..235f5a1 100644 --- a/kexec/kexec-uki.c +++ b/kexec/kexec-uki.c @@ -15,8 +15,10 @@ #define UKI_DTB_SECTION ".dtb" #define FILENAME_UKI_INITRD "/tmp/InitrdXXXXXX" +#define FILENAME_UKI_KERNEL "/tmp/KernelXXXXXX" static int embeded_linux_format_index = -1; +static int kernel_fd = -1; /* * Return -1 if not PE, else offset of the PE header @@ -98,6 +100,15 @@ int uki_image_probe(const char *file_buf, off_t buf_sz) if (linux_sz == -1) { printf("ERR: can not find .linux section\n"); return -1; + } else { + int res; + + res = create_tmpfd(FILENAME_UKI_KERNEL, linux_src, linux_sz, + &kernel_fd); + if (res < 0) { + printf("ERR: can not create tmp file to hold .linux section\n"); + return -1; + } } /* * After stripping the UKI coat, the real kernel format can be handled now. @@ -120,6 +131,9 @@ int uki_image_probe(const char *file_buf, off_t buf_sz) int uki_image_load(int argc, char **argv, const char *buf, off_t len, struct kexec_info *info) { + /* In probe() chain, if nobody sets info->kernel_fd, set it now */ + if (info->kernel_fd == -1) + info->kernel_fd = kernel_fd; return file_type[embeded_linux_format_index].load(argc, argv, buf, len, info); } -- 2.41.0 _______________________________________________ kexec mailing list kexec@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/kexec