diff mbox

[1/6] qcow2: Avoid overflow in alloc_clusters_noref()

Message ID 1398790996-22695-2-git-send-email-mreitz@redhat.com
State New
Headers show

Commit Message

Max Reitz April 29, 2014, 5:03 p.m. UTC
alloc_clusters_noref() stores the cluster index in a uint64_t. However,
offsets are often represented as int64_t (as for example the return
value of alloc_clusters_noref() itself demonstrates). Therefore, we
should make sure all offsets in the allocated range of clusters are
representable using int64_t without overflows.

Signed-off-by: Max Reitz <mreitz@redhat.com>
---
 block/qcow2-refcount.c | 7 +++++++
 1 file changed, 7 insertions(+)

Comments

Kevin Wolf April 30, 2014, 12:45 p.m. UTC | #1
Am 29.04.2014 um 19:03 hat Max Reitz geschrieben:
> alloc_clusters_noref() stores the cluster index in a uint64_t. However,
> offsets are often represented as int64_t (as for example the return
> value of alloc_clusters_noref() itself demonstrates). Therefore, we
> should make sure all offsets in the allocated range of clusters are
> representable using int64_t without overflows.
> 
> Signed-off-by: Max Reitz <mreitz@redhat.com>
> ---
>  block/qcow2-refcount.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
> index a37ee45..e6fc30e 100644
> --- a/block/qcow2-refcount.c
> +++ b/block/qcow2-refcount.c
> @@ -653,6 +653,13 @@ retry:
>              goto retry;
>          }
>      }
> +
> +    /* Make sure that all offsets in the "allocated" range are representable
> +     * in an int64_t */
> +    if (s->free_cluster_index - 1 > (INT64_MAX >> s->cluster_bits)) {
> +        return -E2BIG;
> +    }

I think you mean EFBIG (File too large) rather than E2BIG (Argument list
too long). I'll fix this while applying.

Kevin
diff mbox

Patch

diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index a37ee45..e6fc30e 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -653,6 +653,13 @@  retry:
             goto retry;
         }
     }
+
+    /* Make sure that all offsets in the "allocated" range are representable
+     * in an int64_t */
+    if (s->free_cluster_index - 1 > (INT64_MAX >> s->cluster_bits)) {
+        return -E2BIG;
+    }
+
 #ifdef DEBUG_ALLOC2
     fprintf(stderr, "alloc_clusters: size=%" PRId64 " -> %" PRId64 "\n",
             size,