In kvm__arch_load_kernel_image(), 'limit' is computed to be the topmost byte address where the payload can reside. In all the read_file() calls, the maximum size of the file being read is computed as limit - pos, which is incorrect: either limit is inclusive, and it should be limit - pos + 1, or the maximum size is correct and limit is incorrectly computed as inclusive. After reserving space for the DTB, 'limit' is updated to point at the first byte of the DTB. Which is in contradiction with the way it is initially calculated, because in theory this makes it possible for the initrd (which is copied below the DTB) to overwrite the first byte of the DTB. That's only avoided by accident, and not by design, because, as explained above, the size of the initrd is smaller by 1 byte (read_file() has the size parameter limit - pos, instead of limit - pos + 1). Let's get rid of this confusion and compute 'limit' as exclusive from the start. Signed-off-by: Alexandru Elisei <alexandru.elisei@xxxxxxx> --- arm/kvm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arm/kvm.c b/arm/kvm.c index 9f9582326401..da0430c40c36 100644 --- a/arm/kvm.c +++ b/arm/kvm.c @@ -109,7 +109,7 @@ bool kvm__arch_load_kernel_image(struct kvm *kvm, int fd_kernel, int fd_initrd, * Linux requires the initrd and dtb to be mapped inside lowmem, * so we can't just place them at the top of memory. */ - limit = kvm->ram_start + min(kvm->ram_size, (u64)SZ_256M) - 1; + limit = kvm->ram_start + min(kvm->ram_size, (u64)SZ_256M); pos = kvm->ram_start + kvm__arch_get_kern_offset(kvm, fd_kernel); kvm->arch.kern_guest_start = host_to_guest_flat(kvm, pos); @@ -139,7 +139,7 @@ bool kvm__arch_load_kernel_image(struct kvm *kvm, int fd_kernel, int fd_initrd, kvm->arch.dtb_guest_start = guest_addr; pr_debug("Placing fdt at 0x%llx - 0x%llx", kvm->arch.dtb_guest_start, - host_to_guest_flat(kvm, limit)); + host_to_guest_flat(kvm, limit - 1)); limit = pos; /* ... and finally the initrd, if we have one. */ -- 2.47.0