05bba0
From b8514c8dfe9af1d7c6e5ed3eff1a4383b5da087e Mon Sep 17 00:00:00 2001
05bba0
From: Max Reitz <mreitz@redhat.com>
05bba0
Date: Sat, 13 Jun 2015 16:22:31 +0200
05bba0
Subject: [PATCH 37/42] qcow2: Add two more unalignment checks
05bba0
05bba0
Message-id: <1434212556-3927-38-git-send-email-mreitz@redhat.com>
05bba0
Patchwork-id: 66056
05bba0
O-Subject: [RHEL-7.2 qemu-kvm PATCH 37/42] qcow2: Add two more unalignment checks
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
BZ: 1129893
05bba0
05bba0
This adds checks for unaligned L2 table offsets and unaligned data
05bba0
cluster offsets (actually the preallocated offsets for zero clusters) to
05bba0
the zero cluster expansion function.
05bba0
05bba0
Signed-off-by: Max Reitz <mreitz@redhat.com>
05bba0
Reviewed-by: Eric Blake <eblake@redhat.com>
05bba0
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
05bba0
(cherry picked from commit 8dd93d9339505376f6ce6737ead871ff6d7e676f)
05bba0
05bba0
Signed-off-by: Max Reitz <mreitz@redhat.com>
05bba0
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
05bba0
---
05bba0
 block/qcow2-cluster.c | 21 +++++++++++++++++++++
05bba0
 1 file changed, 21 insertions(+)
05bba0
05bba0
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
05bba0
index 053e9fe..f7938f6 100644
05bba0
--- a/block/qcow2-cluster.c
05bba0
+++ b/block/qcow2-cluster.c
05bba0
@@ -1579,6 +1579,14 @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
05bba0
             continue;
05bba0
         }
05bba0
 
05bba0
+        if (offset_into_cluster(s, l2_offset)) {
05bba0
+            qcow2_signal_corruption(bs, true, -1, -1, "L2 table offset %#"
05bba0
+                                    PRIx64 " unaligned (L1 index: %#x)",
05bba0
+                                    l2_offset, i);
05bba0
+            ret = -EIO;
05bba0
+            goto fail;
05bba0
+        }
05bba0
+
05bba0
         if (is_active_l1) {
05bba0
             /* get active L2 tables from cache */
05bba0
             ret = qcow2_cache_get(bs, s->l2_table_cache, l2_offset,
05bba0
@@ -1638,6 +1646,19 @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
05bba0
                 }
05bba0
             }
05bba0
 
05bba0
+            if (offset_into_cluster(s, offset)) {
05bba0
+                qcow2_signal_corruption(bs, true, -1, -1, "Data cluster offset "
05bba0
+                                        "%#" PRIx64 " unaligned (L2 offset: %#"
05bba0
+                                        PRIx64 ", L2 index: %#x)", offset,
05bba0
+                                        l2_offset, j);
05bba0
+                if (!preallocated) {
05bba0
+                    qcow2_free_clusters(bs, offset, s->cluster_size,
05bba0
+                                        QCOW2_DISCARD_ALWAYS);
05bba0
+                }
05bba0
+                ret = -EIO;
05bba0
+                goto fail;
05bba0
+            }
05bba0
+
05bba0
             ret = qcow2_pre_write_overlap_check(bs, 0, offset, s->cluster_size);
05bba0
             if (ret < 0) {
05bba0
                 if (!preallocated) {
05bba0
-- 
05bba0
1.8.3.1
05bba0