diff options
Diffstat (limited to 'kexec/kexec.c')
-rw-r--r-- | kexec/kexec.c | 42 |
1 files changed, 24 insertions, 18 deletions
diff --git a/kexec/kexec.c b/kexec/kexec.c index 36bb2ade..d132eb53 100644 --- a/kexec/kexec.c +++ b/kexec/kexec.c @@ -638,6 +638,21 @@ char *slurp_decompress_file(const char *filename, off_t *r_size) return kernel_buf; } +static int copybuf_memfd(const char *kernel_buf, size_t size) +{ + int fd, count; + + fd = memfd_create("kernel", MFD_ALLOW_SEALING); + if (fd == -1) + return fd; + + count = write(fd, kernel_buf, size); + if (count < 0) + return -1; + + return fd; +} + static void update_purgatory(struct kexec_info *info) { static const uint8_t null_buf[256]; @@ -1290,31 +1305,22 @@ static int do_kexec_file_load(int fileind, int argc, char **argv, kernel = argv[fileind]; - kernel_fd = open(kernel, O_RDONLY); - if (kernel_fd == -1) { - fprintf(stderr, "Failed to open file %s:%s\n", kernel, + /* slurp in the input kernel */ + kernel_buf = slurp_decompress_file(kernel, &kernel_size); + if (!kernel_buf) { + fprintf(stderr, "Failed to decompress file %s:%s\n", kernel, strerror(errno)); return EFAILED; } - - /* slurp in the input kernel */ - kernel_buf = slurp_decompress_file(kernel, &kernel_size); + kernel_fd = copybuf_memfd(kernel_buf, kernel_size); + if (kernel_fd < 0) { + fprintf(stderr, "Failed to copy decompressed buf\n"); + return EFAILED; + } for (i = 0; i < file_types; i++) { -#ifdef __aarch64__ - /* handle Image.gz like cases */ - if (is_zlib_file(kernel, &kernel_size)) { - if ((ret = file_type[i].probe(kernel, kernel_size)) >= 0) { - kernel_fd = ret; - break; - } - } else - if (file_type[i].probe(kernel_buf, kernel_size) >= 0) - break; -#else if (file_type[i].probe(kernel_buf, kernel_size) >= 0) break; -#endif } if (i == file_types) { |