diff mbox series

[3/4] btrfs-progs: fix rand_range()

Message ID d9997239035f5c71a5efc4a6353f79c3836d0a3e.1720415116.git.wqu@suse.com (mailing list archive)
State New, archived
Headers show
Series btrfs-progs: fix the filename sanitization of btrfs-image | expand

Commit Message

Qu Wenruo July 8, 2024, 5:14 a.m. UTC
[BUG]
Btrfs-image with "-s" option is not properly genearting the desired
range [33, 126], thus even with the filename sanitization fixed, it's
still generate filenames beyond ASCII ranges:

	item 9 key (258 INODE_REF 256) itemoff 15549 itemsize 25
		index 3 namelen 15 name: 1���'�gc*&R

[CAUSE]
It's the function rand_range() return value larger than the specified
@upper.

The cause is in the timing when we trim the value down to 32 bits:

	return (unsigned int)(jrand48(rand_seed) % upper);

Unlike the name, jrand48() generate uniformly distrbuted value between
[-2^31, 2^31 - 1], which is the full range of s32.

And the result of a modulus operation with a minus input is still minus.

Thus even if we later convert it to unsigned int, the minus value is
much larger than @upper and caused the problem.

[FIX]
Convert the value to unsigned int first, then do the modulus operation.
Furthermore to prevent the problem from happening again, add a new
UASSERT() to make sure the result is indeed smaller than @upper.

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 common/utils.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/common/utils.c b/common/utils.c
index 3ca7cff396fe..8f6556b345e8 100644
--- a/common/utils.c
+++ b/common/utils.c
@@ -922,12 +922,12 @@  u32 rand_u32(void)
 /* Return random number in range [0, upper) */
 unsigned int rand_range(unsigned int upper)
 {
+	int ret;
+
 	__init_seed();
-	/*
-	 * Use the full 48bits to mod, which would be more uniformly
-	 * distributed
-	 */
-	return (unsigned int)(jrand48(rand_seed) % upper);
+	ret = (unsigned int)(jrand48(rand_seed)) % upper;
+	UASSERT(ret < upper);
+	return ret;
 }
 
 int rand_int(void)