summaryrefslogtreecommitdiff
path: root/kexec
diff options
context:
space:
mode:
Diffstat (limited to 'kexec')
-rw-r--r--kexec/arch/arm/kexec-zImage-arm.c36
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;