]> granicus.if.org Git - zfs/commitdiff
void integer overflow on computation of refquota_slack
authorColin Ian King <colin.king@canonical.com>
Wed, 27 Jul 2016 08:26:38 +0000 (09:26 +0100)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 27 Jul 2016 20:38:46 +0000 (13:38 -0700)
DMU_MAX_ACCESS should be cast to a uint64_t otherwise the
multiplication of DMU_MAX_ACCESS with spa_asize_inflation will
be 32 bit and may lead to an overflow. Currently DMU_MAX_ACCESS
is 64 * 1024 * 1024, so spa_asize_inflation being 64 or more will
lead to an overflow.

Found by static analysis with CoverityScan 0.8.5

CID 150942 (#1 of 1): Unintentional integer overflow
  (OVERFLOW_BEFORE_WIDEN)
overflow_before_widen: Potentially overflowing expression
  67108864 * spa_asize_inflation with type int (32 bits, signed)
  is evaluated using 32-bit arithmetic, and then used in a context
  that expects an expression of type uint64_t (64 bits, unsigned).

Signed-off-by: Colin Ian King <colin.king@canonical.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #4889

module/zfs/dsl_dataset.c

index 5b7de74dc90d1eabebfe5a5cce3e8964e8e2efe1..1b2ac72b04f339de3262d704d95dbc9070d5e947 100644 (file)
@@ -2836,7 +2836,8 @@ dsl_dataset_clone_swap_check_impl(dsl_dataset_t *clone,
         * "slack" factor for received datasets with refquota set on them.
         * See the bottom of this function for details on its use.
         */
-       uint64_t refquota_slack = DMU_MAX_ACCESS * spa_asize_inflation;
+       uint64_t refquota_slack = (uint64_t)DMU_MAX_ACCESS *
+           spa_asize_inflation;
        int64_t unused_refres_delta;
 
        /* they should both be heads */