From cf1cff8344bbc2dee15456f80ca06e957e3a922f Mon Sep 17 00:00:00 2001 From: Martin Minkus Date: Wed, 16 Sep 2026 00:23:05 -0700 Subject: [PATCH] libdevs: make the safe device bitmap word unsigned SDEV_BITMAP_WORD is long, so sdev_is_block_saved() and sdev_mark_blocks() evaluate (long)1 << 63 whenever a block position is congruent to 63 modulo 64. Shifting into the sign bit of a signed type is undefined behaviour. gcc currently produces the intended bit pattern, so the bitmap happens to work, but the behaviour is not guaranteed and the bitmap is what the safe device uses to decide whether a block has already been saved. A wrong answer there would either lose an original block or consume the saved block budget twice. Building with -fsanitize=undefined and probing a simulated device reports the shift on every run: src/libdevs.c:1158:32: runtime error: left shift of 1 by 63 places cannot be represented in type 'long int' src/libdevs.c:1170:51: runtime error: left shift of 1 by 63 places cannot be represented in type 'long int' Across 63 simulated geometries, every run flagged it. With the word made unsigned, none do, and every probed size is unchanged. --- src/libdevs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libdevs.c b/src/libdevs.c index 7348d8c..7471af8 100644 --- a/src/libdevs.c +++ b/src/libdevs.c @@ -1110,7 +1110,7 @@ void perf_device_sample(struct device *dev, *preset_time_ns = pdev->reset_time_ns; } -#define SDEV_BITMAP_WORD long +#define SDEV_BITMAP_WORD unsigned long #define SDEV_BITMAP_BITS_PER_WORD (8*sizeof(SDEV_BITMAP_WORD)) struct safe_device { /* This must be the first field. See dev_sdev() for details. */