Commit 08546bcf authored by Max Reitz's avatar Max Reitz
Browse files

qcow2: Fix overly broad madvise()



@mem_size and @offset are both size_t, thus subtracting them from one
another will just return a big size_t if mem_size < offset -- even more
obvious here because the result is stored in another size_t.

Checking that result to be positive is therefore not sufficient to
exclude the case that offset > mem_size.  Thus, we currently sometimes
issue an madvise() over a very large address range.

This is triggered by iotest 163, but with -m64, this does not result in
tangible problems.  But with -m32, this test produces three segfaults,
all of which are fixed by this patch.

Signed-off-by: default avatarMax Reitz <mreitz@redhat.com>
Message-id: 20171114184127.24238-1-mreitz@redhat.com
Reviewed-by: default avatarEric Blake <eblake@redhat.com>
Reviewed-by: default avatarAlberto Garcia <berto@igalia.com>
Reviewed-by: default avatarDarren Kenny <darren.kenny@oracle.com>
Signed-off-by: default avatarMax Reitz <mreitz@redhat.com>
parent 4efb1f7c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -85,7 +85,7 @@ static void qcow2_cache_table_release(BlockDriverState *bs, Qcow2Cache *c,
    size_t mem_size = (size_t) s->cluster_size * num_tables;
    size_t offset = QEMU_ALIGN_UP((uintptr_t) t, align) - (uintptr_t) t;
    size_t length = QEMU_ALIGN_DOWN(mem_size - offset, align);
    if (length > 0) {
    if (mem_size > offset && length > 0) {
        madvise((uint8_t *) t + offset, length, MADV_DONTNEED);
    }
#endif