diff options
author | Chuck Tuffli <[email protected]> | 2020-10-08 16:37:27 -0700 |
---|---|---|
committer | GitHub <[email protected]> | 2020-10-08 16:37:27 -0700 |
commit | a8fc1b8743f1abfe6b9c5922f6d7617d4959d51d (patch) | |
tree | 17f204e34aad9e243a5519b517d8dabe82986a21 | |
parent | 36482bf607735598abf660a17a2adc2244353c2b (diff) |
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 <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Reviewed-by: Ryan Moeller <[email protected]>
Signed-off-by: Chuck Tuffli <[email protected]>
Closes #9744
Closes #11024
-rw-r--r-- | module/zfs/vdev_label.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/module/zfs/vdev_label.c b/module/zfs/vdev_label.c index 7fab7d0d7..1c502b9e0 100644 --- a/module/zfs/vdev_label.c +++ b/module/zfs/vdev_label.c @@ -613,7 +613,8 @@ vdev_config_generate(spa_t *spa, vdev_t *vd, boolean_t getstats, * as a single mapping. */ 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 += vd->vdev_mg->mg_histogram[i] << (i + 1); |