diff options
author | Kevin Wolf <kwolf@redhat.com> | 2014-03-26 13:05:52 +0100 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2014-04-01 15:22:35 +0200 |
commit | 0abe740f1de899737242bcba1fb4a9857f7a3087 (patch) | |
tree | 782b63858caae14f3d40e70eddd23c7d0f754bf0 /block/qcow2-refcount.c | |
parent | bb572aefbdac290363bfa5ca0e810ccce0a14ed6 (diff) |
qcow2: Protect against some integer overflows in bdrv_check
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'block/qcow2-refcount.c')
-rw-r--r-- | block/qcow2-refcount.c | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index 9130042367..a37ee45016 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -1020,8 +1020,7 @@ static void inc_refcounts(BlockDriverState *bs, int64_t offset, int64_t size) { BDRVQcowState *s = bs->opaque; - int64_t start, last, cluster_offset; - int k; + uint64_t start, last, cluster_offset, k; if (size <= 0) return; @@ -1031,11 +1030,7 @@ static void inc_refcounts(BlockDriverState *bs, for(cluster_offset = start; cluster_offset <= last; cluster_offset += s->cluster_size) { k = cluster_offset >> s->cluster_bits; - if (k < 0) { - fprintf(stderr, "ERROR: invalid cluster offset=0x%" PRIx64 "\n", - cluster_offset); - res->corruptions++; - } else if (k >= refcount_table_size) { + if (k >= refcount_table_size) { fprintf(stderr, "Warning: cluster offset=0x%" PRIx64 " is after " "the end of the image file, can't properly check refcounts.\n", cluster_offset); @@ -1478,14 +1473,19 @@ int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix) { BDRVQcowState *s = bs->opaque; - int64_t size, i, highest_cluster; - int nb_clusters, refcount1, refcount2; + int64_t size, i, highest_cluster, nb_clusters; + int refcount1, refcount2; QCowSnapshot *sn; uint16_t *refcount_table; int ret; size = bdrv_getlength(bs->file); nb_clusters = size_to_clusters(s, size); + if (nb_clusters > INT_MAX) { + res->check_errors++; + return -EFBIG; + } + refcount_table = g_malloc0(nb_clusters * sizeof(uint16_t)); res->bfi.total_clusters = |