libdevs: make the safe device bitmap word unsigned - #288
Merged
AltraMayor merged 1 commit intoSep 16, 2026
Merged
Conversation
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.
Owner
|
Thank you for this review, @mminkus. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
SDEV_BITMAP_WORDislong, sosdev_is_block_saved()andsdev_mark_blocks()evaluate
(long)1 << 63whenever a block position is congruent to 63 modulo 64.Shifting into the sign bit of a signed type is undefined behaviour.
In practice gcc produces the intended bit pattern today, so the bitmap happens to
work. It is still UB, and the bitmap is what the safe device uses to decide
whether a block has already been saved, so a wrong answer there would either lose
an original block or consume the saved block budget twice.
Reproducing
Build with UBSan and probe a simulated device:
Verifying the fix
I swept 63 simulated geometries, varying real size, announced size and wrap.
Every run reported the shift before this change; none do after it, and every
probed size is identical either way, so this is a pure UB fix with no behaviour
change.
Found while probing a counterfeit card on aarch64, Debian 13, gcc 14.2.