diff mbox

[v3,2/4] qcow2: fix offset overflow in qcow2_alloc_clusters_at()

Message ID c1a0ad2294bda973b06f9e323aeed7b11f29c53b.1390373621.git.hutao@cn.fujitsu.com
State New
Headers show

Commit Message

Hu Tao Jan. 22, 2014, 6:57 a.m. UTC
When cluster size is big enough it can lead offset overflow
in qcow2_alloc_clusters_at(). This patch fixes it.

The allocation each time is stopped at L2 table boundary
(see handle_alloc()), so the possible maximum bytes could be

  2^(cluster_bits - 3 + cluster_bits)

so int is safe for cluster_bits<=17, unsafe otherwise.

Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
---
 block/qcow2-refcount.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

Comments

Max Reitz Jan. 22, 2014, 7:16 p.m. UTC | #1
On 22.01.2014 07:57, Hu Tao wrote:
> When cluster size is big enough it can lead offset overflow
> in qcow2_alloc_clusters_at(). This patch fixes it.
>
> The allocation each time is stopped at L2 table boundary
> (see handle_alloc()), so the possible maximum bytes could be
>
>    2^(cluster_bits - 3 + cluster_bits)
>
> so int is safe for cluster_bits<=17, unsafe otherwise.
>
> Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
> ---
>   block/qcow2-refcount.c | 8 +++++++-
>   1 file changed, 7 insertions(+), 1 deletion(-)

Reviewed-by: Max Reitz <mreitz@redhat.com>
Hu Tao Jan. 23, 2014, 2:53 a.m. UTC | #2
On Wed, Jan 22, 2014 at 08:16:44PM +0100, Max Reitz wrote:
> On 22.01.2014 07:57, Hu Tao wrote:
> >When cluster size is big enough it can lead offset overflow
> >in qcow2_alloc_clusters_at(). This patch fixes it.
> >
> >The allocation each time is stopped at L2 table boundary
> >(see handle_alloc()), so the possible maximum bytes could be
> >
> >   2^(cluster_bits - 3 + cluster_bits)
> >
> >so int is safe for cluster_bits<=17, unsafe otherwise.
> >
> >Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
> >---
> >  block/qcow2-refcount.c | 8 +++++++-
> >  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> Reviewed-by: Max Reitz <mreitz@redhat.com>

Thanks for reviewing!
diff mbox

Patch

diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index c974abe..8712d8b 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -676,7 +676,13 @@  int qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset,
     BDRVQcowState *s = bs->opaque;
     uint64_t cluster_index;
     uint64_t old_free_cluster_index;
-    int i, refcount, ret;
+    uint64_t i;
+    int refcount, ret;
+
+    assert(nb_clusters >= 0);
+    if (nb_clusters == 0) {
+        return 0;
+    }
 
     /* Check how many clusters there are free */
     cluster_index = offset >> s->cluster_bits;