[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[qemu-xen staging-4.13] qcow2: Limit total allocation range to INT_MAX



commit 9e51c5306cffe1a0904d1a31fcf454c436ce8a13
Author:     Max Reitz <mreitz@xxxxxxxxxx>
AuthorDate: Thu Oct 10 12:08:57 2019 +0200
Commit:     Michael Roth <mdroth@xxxxxxxxxxxxxxxxxx>
CommitDate: Mon Nov 4 08:15:25 2019 -0600

    qcow2: Limit total allocation range to INT_MAX
    
    When the COW areas are included, the size of an allocation can exceed
    INT_MAX.  This is kind of limited by handle_alloc() in that it already
    caps avail_bytes at INT_MAX, but the number of clusters still reflects
    the original length.
    
    This can have all sorts of effects, ranging from the storage layer write
    call failing to image corruption.  (If there were no image corruption,
    then I suppose there would be data loss because the .cow_end area is
    forced to be empty, even though there might be something we need to
    COW.)
    
    Fix all of it by limiting nb_clusters so the equivalent number of bytes
    will not exceed INT_MAX.
    
    Cc: qemu-stable@xxxxxxxxxx
    Signed-off-by: Max Reitz <mreitz@xxxxxxxxxx>
    Reviewed-by: Eric Blake <eblake@xxxxxxxxxx>
    Reviewed-by: Philippe Mathieu-Daudé <philmd@xxxxxxxxxx>
    Signed-off-by: Kevin Wolf <kwolf@xxxxxxxxxx>
    (cherry picked from commit d1b9d19f99586b33795e20a79f645186ccbc070f)
    Signed-off-by: Michael Roth <mdroth@xxxxxxxxxxxxxxxxxx>
---
 block/qcow2-cluster.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 760564c8fb..f8576031b6 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -1341,6 +1341,9 @@ static int handle_alloc(BlockDriverState *bs, uint64_t 
guest_offset,
     nb_clusters = MIN(nb_clusters, s->l2_slice_size - l2_index);
     assert(nb_clusters <= INT_MAX);
 
+    /* Limit total allocation byte count to INT_MAX */
+    nb_clusters = MIN(nb_clusters, INT_MAX >> s->cluster_bits);
+
     /* Find L2 entry for the first involved cluster */
     ret = get_cluster_table(bs, guest_offset, &l2_slice, &l2_index);
     if (ret < 0) {
@@ -1429,7 +1432,7 @@ static int handle_alloc(BlockDriverState *bs, uint64_t 
guest_offset,
      * request actually writes to (excluding COW at the end)
      */
     uint64_t requested_bytes = *bytes + offset_into_cluster(s, guest_offset);
-    int avail_bytes = MIN(INT_MAX, nb_clusters << s->cluster_bits);
+    int avail_bytes = nb_clusters << s->cluster_bits;
     int nb_bytes = MIN(requested_bytes, avail_bytes);
     QCowL2Meta *old_m = *m;
 
--
generated by git-patchbot for /home/xen/git/qemu-xen.git#staging-4.13



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.