summaryrefslogtreecommitdiff
path: root/kexec/kexec-uImage.c
diff options
context:
space:
mode:
authorSuzuki K. Poulose <suzuki@in.ibm.com>2013-03-06 14:09:47 +0530
committerSimon Horman <horms@verge.net.au>2013-03-08 13:57:30 +0900
commit90f7609a739d24faffab41422185b9f1a65573da (patch)
tree51a3856d516d30c2b3250e49219d3a3dd3c47336 /kexec/kexec-uImage.c
parent4255d2b07d231a3ff037fdf5aafa80e4f90c937d (diff)
kexec/uImage: Fix the payload length in uImage_load
For payloads without any compression, the image->len is set to the length of the entire uImage which includes the uImage header. This should be filled in from ih_size field of the uImage header. This can cause a buffer overflow, leading the sha256_process to overrun the initrd buffer. Also, prevents a vulnerability where the image has been appended with additional data. The crc check is performed only when compiled with zlib. TODO: Implement CRC check if ZLIB is not compiled in. Reported-by: Nathan Miller <nathanm2@us.ibm.com> Signed-off-by: Suzuki K. Poulose <suzuki@in.ibm.com> Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'kexec/kexec-uImage.c')
-rw-r--r--kexec/kexec-uImage.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/kexec/kexec-uImage.c b/kexec/kexec-uImage.c
index 3799a3b..9e275b2 100644
--- a/kexec/kexec-uImage.c
+++ b/kexec/kexec-uImage.c
@@ -208,14 +208,25 @@ int uImage_load(const unsigned char *buf, off_t len, struct Image_info *image)
{
const struct image_header *header = (const struct image_header *)buf;
const unsigned char *img_buf = buf + sizeof(struct image_header);
- off_t img_len = len - sizeof(struct image_header);
+ off_t img_len = header->ih_size;
+
+ /*
+ * Prevent loading a modified image.
+ * CRC check is perfomed only when zlib is compiled
+ * in. This check will help us to detect
+ * size related vulnerabilities.
+ */
+ if (img_len != (len - sizeof(struct image_header))) {
+ printf("Image size doesn't match the header\n");
+ return -1;
+ }
image->base = cpu_to_be32(header->ih_load);
image->ep = cpu_to_be32(header->ih_ep);
switch (header->ih_comp) {
case IH_COMP_NONE:
image->buf = img_buf;
- image->len = len;
+ image->len = img_len;
return 0;
break;