summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2010-02-16 15:54:49 +0100
committerAnthony Liguori <aliguori@us.ibm.com>2010-02-23 14:07:58 -0600
commit5dde87088ffaac0b3b873523c07e941c18f2529e (patch)
tree4aedc1cb363e0d00615c31d8bfff1823248ea940
parent3fa017e24b0a0f0e68619a689b9b02fe486dae9e (diff)
downloadqemu-5dde87088ffaac0b3b873523c07e941c18f2529e.tar.gz
qcow2: Fix access after end of array
If a write requests crosses a L2 table boundary and all clusters until the end of the L2 table are usable for the request, we must not look at the next L2 entry because we already have arrived at the end of the array. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> (cherry picked from commit 4805bb66969622f86376191c94c4748bce91e6be)
-rw-r--r--block/qcow2-cluster.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 3501a94296..b13b6935f8 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -750,12 +750,15 @@ int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
while (i < nb_clusters) {
i += count_contiguous_clusters(nb_clusters - i, s->cluster_size,
&l2_table[l2_index], i, 0);
-
- if(be64_to_cpu(l2_table[l2_index + i]))
+ if ((i >= nb_clusters) || be64_to_cpu(l2_table[l2_index + i])) {
break;
+ }
i += count_contiguous_free_clusters(nb_clusters - i,
&l2_table[l2_index + i]);
+ if (i >= nb_clusters) {
+ break;
+ }
cluster_offset = be64_to_cpu(l2_table[l2_index + i]);
@@ -763,6 +766,7 @@ int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
(cluster_offset & QCOW_OFLAG_COMPRESSED))
break;
}
+ assert(i <= nb_clusters);
nb_clusters = i;
/*