From d13533fb4dada401eb437454ce348caa1ab94fe6 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Fri, 28 Mar 2014 18:46:57 +0100 Subject: [PATCH 1/2] qcow2: fix dangling refcount table entry RH-Author: Stefan Hajnoczi Message-id: <1396032417-10176-1-git-send-email-stefanha@redhat.com> Patchwork-id: 58281 O-Subject: [RHEL7 qemu-kvm PATCH] qcow2: fix dangling refcount table entry Bugzilla: 1081793 RH-Acked-by: Fam Zheng RH-Acked-by: Kevin Wolf RH-Acked-by: Juan Quintela BZ: 1081793 Upstream: Downstream only but same fix in https://lists.gnu.org/archive/html/qemu-devel/2014-03/msg05605.html BREW: http://brewweb.devel.redhat.com/brew/taskinfo?taskID=7272001 In qcow2_create2() we first manually populate a minimal image file with the qcow2 header, refcount table, and one refcount block. Then can open the minimal image as a valid file and fill in the remaining information. In commit a2b10eec76a72aa7fe63e797181b93f69de9600e ("qcow2: Don't rely on free_cluster_index in alloc_refcount_block() (CVE-2014-0147)") a dangling refcount table entry was introduced. This works for image files but fails for host block devices that already contain data because we follow the dangling refcount table entry and read bogus data. This patch zeroes the refcount block so the refcount table entry is pointing to initialized data. This patch is downstream-only because the broken commit was not merged yet upstream. Therefore upstream has a v2 patch but we need a separate bugfix for downstream. Signed-off-by: Stefan Hajnoczi --- block/qcow2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) Signed-off-by: Miroslav Rezanina --- block/qcow2.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index 3f8febc..66ed906 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1628,9 +1628,9 @@ static int qcow2_create2(const char *filename, int64_t total_size, } /* Write a refcount table with one refcount block */ - refcount_table = g_malloc0(cluster_size); + refcount_table = g_malloc0(2 * cluster_size); refcount_table[0] = cpu_to_be64(2 * cluster_size); - ret = bdrv_pwrite(bs, cluster_size, refcount_table, cluster_size); + ret = bdrv_pwrite(bs, cluster_size, refcount_table, 2 * cluster_size); g_free(refcount_table); if (ret < 0) { -- 1.7.1