From 0df5b5737c124d06f31721e2f09cc3dc7c5c87ad Mon Sep 17 00:00:00 2001 From: Chuck Tuffli Date: Thu, 8 Oct 2020 16:37:27 -0700 Subject: [PATCH] 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 Reviewed-by: Brian Behlendorf Reviewed-by: Ryan Moeller Signed-off-by: Chuck Tuffli Closes #9744 Closes #11024 --- module/zfs/vdev_label.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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);