Fix ubsan: shift exponent is too large

When running libzpool with the Undefined Behavior Sanitizer (ubsan)
enabled, a zpool create causes a run-time error:

    module/zfs/vdev_label.c:600:14: runtime error: shift exponent 64 is
    too large for 64-bit type 'long long unsigned int'`

in vdev_config_generate()

Fix is to convert vdev_removal_max_span to its base-2 logarithm, using
highbit64(), and then compare the "shifts".

Reviewed-by: Matthew Ahrens <mahrens@delphix.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Ryan Moeller <ryan@iXsystems.com>
Signed-off-by: Chuck Tuffli <ctuffli@gmail.com>
Closes #9744
Closes #11024
This commit is contained in:
Chuck Tuffli 2020-10-08 16:37:27 -07:00 committed by Brian Behlendorf
parent 102a1db6b2
commit 0df5b5737c

View File

@ -613,7 +613,8 @@ vdev_config_generate(spa_t *spa, vdev_t *vd, boolean_t getstats,
* as a single mapping. * as a single mapping.
*/ */
for (int i = 0; i < RANGE_TREE_HISTOGRAM_SIZE; i++) { for (int i = 0; i < RANGE_TREE_HISTOGRAM_SIZE; i++) {
if (1ULL << (i + 1) < vdev_removal_max_span) { if (i + 1 < highbit64(vdev_removal_max_span)
- 1) {
to_alloc += to_alloc +=
vd->vdev_mg->mg_histogram[i] << vd->vdev_mg->mg_histogram[i] <<
(i + 1); (i + 1);