diff options
Diffstat (limited to 'kexec')
-rw-r--r-- | kexec/arch/arm/kexec-zImage-arm.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/kexec/arch/arm/kexec-zImage-arm.c b/kexec/arch/arm/kexec-zImage-arm.c index c8b90f9..7f02b93 100644 --- a/kexec/arch/arm/kexec-zImage-arm.c +++ b/kexec/arch/arm/kexec-zImage-arm.c @@ -28,6 +28,14 @@ off_t initrd_base = 0, initrd_size = 0; unsigned int kexec_arm_image_size = 0; unsigned long long user_page_offset = (-1ULL); +struct zimage_header { + uint32_t instr[9]; + uint32_t magic; +#define ZIMAGE_MAGIC cpu_to_le32(0x016f2818) + uint32_t start; + uint32_t end; +}; + struct android_image { char magic[8]; uint32_t kernel_size; @@ -435,6 +443,34 @@ int zImage_arm_load(int argc, char **argv, const char *buf, off_t len, if (dtb_file) dtb_buf = slurp_file(dtb_file, &dtb_length); + if (len > 0x34) { + const struct zimage_header *hdr; + off_t size; + + hdr = (const struct zimage_header *)buf; + + dbgprintf("zImage header: 0x%08x 0x%08x 0x%08x\n", + hdr->magic, hdr->start, hdr->end); + + if (hdr->magic == ZIMAGE_MAGIC) { + size = le32_to_cpu(hdr->end) - le32_to_cpu(hdr->start); + + dbgprintf("zImage size 0x%llx, file size 0x%llx\n", + (unsigned long long)size, + (unsigned long long)len); + + if (size > len) { + fprintf(stderr, + "zImage is truncated - file 0x%llx vs header 0x%llx\n", + (unsigned long long)len, + (unsigned long long)size); + return -1; + } + if (size < len) + len = size; + } + } + /* Handle android images, 2048 is the minimum page size */ if (len > 2048 && !strncmp(buf, "ANDROID!", 8)) { const struct android_image *aimg = (const void *)buf; |