Blame SOURCES/kvm-qcow2-Fix-L1-allocation-size-in-qcow2_snapshot_load_.patch

0a122b
From 1235b1580890e2a034bb24f89a89311d296d2622 Mon Sep 17 00:00:00 2001
0a122b
From: Kevin Wolf <kwolf@redhat.com>
0a122b
Date: Tue, 25 Mar 2014 14:23:51 +0100
0a122b
Subject: [PATCH 44/49] qcow2: Fix L1 allocation size in qcow2_snapshot_load_tmp() (CVE-2014-0145)
0a122b
0a122b
RH-Author: Kevin Wolf <kwolf@redhat.com>
0a122b
Message-id: <1395753835-7591-45-git-send-email-kwolf@redhat.com>
0a122b
Patchwork-id: n/a
0a122b
O-Subject: [virt-devel] [EMBARGOED RHEL-7.0 qemu-kvm PATCH 44/48] qcow2: Fix L1 allocation size in qcow2_snapshot_load_tmp() (CVE-2014-0145)
0a122b
Bugzilla: 1079325
0a122b
RH-Acked-by: Jeff Cody <jcody@redhat.com>
0a122b
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
0a122b
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
0a122b
0a122b
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1079325
0a122b
Upstream status: Embargoed
0a122b
0a122b
For the L1 table to loaded for an internal snapshot, the code allocated
0a122b
only enough memory to hold the currently active L1 table. If the
0a122b
snapshot's L1 table is actually larger than the current one, this leads
0a122b
to a buffer overflow.
0a122b
0a122b
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
0a122b
---
0a122b
 block/qcow2-snapshot.c     |    2 +-
0a122b
 tests/qemu-iotests/029     |   18 +++++++++++++++++-
0a122b
 tests/qemu-iotests/029.out |    4 ++++
0a122b
 3 files changed, 22 insertions(+), 2 deletions(-)
0a122b
0a122b
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
0a122b
index 5d73506..b29f7bd 100644
0a122b
--- a/block/qcow2-snapshot.c
0a122b
+++ b/block/qcow2-snapshot.c
0a122b
@@ -635,7 +635,7 @@ int qcow2_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_name)
0a122b
     sn = &s->snapshots[snapshot_index];
0a122b
 
0a122b
     /* Allocate and read in the snapshot's L1 table */
0a122b
-    new_l1_bytes = s->l1_size * sizeof(uint64_t);
0a122b
+    new_l1_bytes = sn->l1_size * sizeof(uint64_t);
0a122b
     new_l1_table = g_malloc0(align_offset(new_l1_bytes, 512));
0a122b
 
0a122b
     ret = bdrv_pread(bs->file, sn->l1_table_offset, new_l1_table, new_l1_bytes);
0a122b
diff --git a/tests/qemu-iotests/029 b/tests/qemu-iotests/029
0a122b
index 567e071..fa46ace 100755
0a122b
--- a/tests/qemu-iotests/029
0a122b
+++ b/tests/qemu-iotests/029
0a122b
@@ -30,7 +30,8 @@ status=1	# failure is the default!
0a122b
 
0a122b
 _cleanup()
0a122b
 {
0a122b
-	_cleanup_test_img
0a122b
+    rm -f $TEST_IMG.snap
0a122b
+    _cleanup_test_img
0a122b
 }
0a122b
 trap "_cleanup; exit \$status" 0 1 2 3 15
0a122b
 
0a122b
@@ -44,6 +45,9 @@ _supported_fmt qcow2
0a122b
 _supported_proto generic
0a122b
 _supported_os Linux
0a122b
 
0a122b
+offset_size=24
0a122b
+offset_l1_size=36
0a122b
+
0a122b
 echo
0a122b
 echo Test loading internal snapshots where the L1 table of the snapshot
0a122b
 echo is smaller than the current L1 table.
0a122b
@@ -77,6 +81,18 @@ _make_test_img 64M
0a122b
 _check_test_img
0a122b
 
0a122b
 
0a122b
+echo
0a122b
+echo "qcow2_snapshot_load_tmp() should take the L1 size from the snapshot"
0a122b
+echo
0a122b
+
0a122b
+CLUSTER_SIZE=512
0a122b
+_make_test_img 64M
0a122b
+{ $QEMU_IMG snapshot -c foo $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
0a122b
+poke_file "$TEST_IMG" "$offset_size" "\x00\x00\x00\x00\x00\x00\x02\x00"
0a122b
+poke_file "$TEST_IMG" "$offset_l1_size" "\x00\x00\x00\x01"
0a122b
+{ $QEMU_IMG convert -s foo $TEST_IMG $TEST_IMG.snap; } 2>&1 | _filter_qemu_io | _filter_testdir
0a122b
+
0a122b
+
0a122b
 # success, all done
0a122b
 echo "*** done"
0a122b
 rm -f $seq.full
0a122b
diff --git a/tests/qemu-iotests/029.out b/tests/qemu-iotests/029.out
0a122b
index 9029698..ce0e64d 100644
0a122b
--- a/tests/qemu-iotests/029.out
0a122b
+++ b/tests/qemu-iotests/029.out
0a122b
@@ -20,4 +20,8 @@ wrote 4096/4096 bytes at offset 1099511627776
0a122b
 read 4096/4096 bytes at offset 1099511627776
0a122b
 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
0a122b
 No errors were found on the image.
0a122b
+
0a122b
+qcow2_snapshot_load_tmp() should take the L1 size from the snapshot
0a122b
+
0a122b
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 
0a122b
 *** done
0a122b
-- 
0a122b
1.7.1
0a122b