aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2019-05-16 15:47:31 +0100
committerPeter Maydell <peter.maydell@linaro.org>2019-06-17 15:11:18 +0100
commit852dc64d665f89d8b54dd9aa7e36c3ff12bef775 (patch)
tree63b1caeb041967bf57ab9d88195c634c58f172e5
parente70af24b42190481e19c9adb727b97a0fc794ea8 (diff)
downloadqemu-852dc64d665f89d8b54dd9aa7e36c3ff12bef775.zip
qemu-852dc64d665f89d8b54dd9aa7e36c3ff12bef775.tar.gz
qemu-852dc64d665f89d8b54dd9aa7e36c3ff12bef775.tar.bz2
hw/arm/boot: Diagnose layouts that put initrd or DTB off the end of RAM
We calculate the locations in memory where we want to put the initrd and the DTB based on the size of the kernel, since they come after it. Add some explicit checks that these aren't off the end of RAM entirely. (At the moment the way we calculate the initrd_start means that it can't ever be off the end of RAM, but that will change with the next commit.) Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Tested-by: Mark Rutland <mark.rutland@arm.com> Message-id: 20190516144733.32399-3-peter.maydell@linaro.org
-rw-r--r--hw/arm/boot.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index bb37a93..5ddba72 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -1056,11 +1056,25 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
error_report("could not load kernel '%s'", info->kernel_filename);
exit(1);
}
+
+ if (kernel_size > info->ram_size) {
+ error_report("kernel '%s' is too large to fit in RAM "
+ "(kernel size %d, RAM size %" PRId64 ")",
+ info->kernel_filename, kernel_size, info->ram_size);
+ exit(1);
+ }
+
info->entry = entry;
if (is_linux) {
uint32_t fixupcontext[FIXUP_MAX];
if (info->initrd_filename) {
+
+ if (info->initrd_start >= ram_end) {
+ error_report("not enough space after kernel to load initrd");
+ exit(1);
+ }
+
initrd_size = load_ramdisk_as(info->initrd_filename,
info->initrd_start,
ram_end - info->initrd_start, as);
@@ -1076,6 +1090,11 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
info->initrd_filename);
exit(1);
}
+ if (info->initrd_start + initrd_size > info->ram_size) {
+ error_report("could not load initrd '%s': "
+ "too big to fit into RAM after the kernel",
+ info->initrd_filename);
+ }
} else {
initrd_size = 0;
}
@@ -1111,6 +1130,10 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
/* Place the DTB after the initrd in memory with alignment. */
info->dtb_start = QEMU_ALIGN_UP(info->initrd_start + initrd_size,
align);
+ if (info->dtb_start >= ram_end) {
+ error_report("Not enough space for DTB after kernel/initrd");
+ exit(1);
+ }
fixupcontext[FIXUP_ARGPTR_LO] = info->dtb_start;
fixupcontext[FIXUP_ARGPTR_HI] = info->dtb_start >> 32;
} else {