05bba0
From 197c8b66cc0b7cc239075b4c86b0f118194e198a Mon Sep 17 00:00:00 2001
05bba0
From: Max Reitz <mreitz@redhat.com>
05bba0
Date: Sat, 13 Jun 2015 16:22:28 +0200
05bba0
Subject: [PATCH 34/42] qcow2: Fix header extension size check
05bba0
05bba0
Message-id: <1434212556-3927-35-git-send-email-mreitz@redhat.com>
05bba0
Patchwork-id: 66053
05bba0
O-Subject: [RHEL-7.2 qemu-kvm PATCH 34/42] qcow2: Fix header extension size check
05bba0
Bugzilla: 1129893
05bba0
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
05bba0
RH-Acked-by: Fam Zheng <famz@redhat.com>
05bba0
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
05bba0
05bba0
From: Kevin Wolf <kwolf@redhat.com>
05bba0
05bba0
BZ: 1129893
05bba0
05bba0
After reading the extension header, offset is incremented, but not
05bba0
checked against end_offset any more. This way an integer overflow could
05bba0
happen when checking whether the extension end is within the allowed
05bba0
range, effectively disabling the check.
05bba0
05bba0
This patch adds the missing check and a test case for it.
05bba0
05bba0
Cc: qemu-stable@nongnu.org
05bba0
Reported-by: Max Reitz <mreitz@redhat.com>
05bba0
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
05bba0
Reviewed-by: Max Reitz <mreitz@redhat.com>
05bba0
Message-id: 1416935562-7760-2-git-send-email-kwolf@redhat.com
05bba0
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
05bba0
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
05bba0
(cherry picked from commit 2ebafc854d109ff09b66fb4dd62c2c53fc29754a)
05bba0
05bba0
Signed-off-by: Max Reitz <mreitz@redhat.com>
05bba0
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
05bba0
---
05bba0
 block/qcow2.c              | 2 +-
05bba0
 tests/qemu-iotests/080     | 2 ++
05bba0
 tests/qemu-iotests/080.out | 2 ++
05bba0
 3 files changed, 5 insertions(+), 1 deletion(-)
05bba0
05bba0
diff --git a/block/qcow2.c b/block/qcow2.c
05bba0
index 4e60077..991c41f 100644
05bba0
--- a/block/qcow2.c
05bba0
+++ b/block/qcow2.c
05bba0
@@ -116,7 +116,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
05bba0
 #ifdef DEBUG_EXT
05bba0
         printf("ext.magic = 0x%x\n", ext.magic);
05bba0
 #endif
05bba0
-        if (ext.len > end_offset - offset) {
05bba0
+        if (offset > end_offset || ext.len > end_offset - offset) {
05bba0
             error_setg(errp, "Header extension too large");
05bba0
             return -EINVAL;
05bba0
         }
05bba0
diff --git a/tests/qemu-iotests/080 b/tests/qemu-iotests/080
05bba0
index 6b3a3e7..b9f9630 100755
05bba0
--- a/tests/qemu-iotests/080
05bba0
+++ b/tests/qemu-iotests/080
05bba0
@@ -78,6 +78,8 @@ poke_file "$TEST_IMG" "$offset_backing_file_offset" "\xff\xff\xff\xff\xff\xff\xf
05bba0
 poke_file "$TEST_IMG" "$offset_ext_magic" "\x12\x34\x56\x78"
05bba0
 poke_file "$TEST_IMG" "$offset_ext_size" "\x7f\xff\xff\xff"
05bba0
 { $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
05bba0
+poke_file "$TEST_IMG" "$offset_backing_file_offset" "\x00\x00\x00\x00\x00\x00\x00\x$(printf %x $offset_ext_size)"
05bba0
+{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
05bba0
 poke_file "$TEST_IMG" "$offset_backing_file_offset" "\x00\x00\x00\x00\x00\x00\x00\x00"
05bba0
 { $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
05bba0
 
05bba0
diff --git a/tests/qemu-iotests/080.out b/tests/qemu-iotests/080.out
05bba0
index 1fa0672..b7db555 100644
05bba0
--- a/tests/qemu-iotests/080.out
05bba0
+++ b/tests/qemu-iotests/080.out
05bba0
@@ -13,6 +13,8 @@ qemu-io: can't open device TEST_DIR/t.qcow2: Invalid backing file offset
05bba0
 no file open, try 'help open'
05bba0
 qemu-io: can't open device TEST_DIR/t.qcow2: Header extension too large
05bba0
 no file open, try 'help open'
05bba0
+qemu-io: can't open device TEST_DIR/t.qcow2: Header extension too large
05bba0
+no file open, try 'help open'
05bba0
 
05bba0
 == Huge refcount table size ==
05bba0
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 
05bba0
-- 
05bba0
1.8.3.1
05bba0