qcow2: Fix access after end of array
authorKevin Wolf <kwolf@redhat.com>
Tue, 16 Feb 2010 14:54:49 +0000 (15:54 +0100)
committerAnthony Liguori <aliguori@us.ibm.com>
Fri, 19 Feb 2010 21:53:54 +0000 (15:53 -0600)
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>
block/qcow2-cluster.c

index 3501a94296df431c0692c56553e545c9364a5c99..b13b6935f80d90a70729d62239e2f2e37d050b74 100644 (file)
@@ -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;
 
     /*