diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/random.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c index 6f323344d0b9..f5868dddbb61 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -161,6 +161,8 @@ EXPORT_SYMBOL(wait_for_random_bytes); * u16 get_random_u16() * u32 get_random_u32() * u32 get_random_u32_below(u32 ceil) + * u32 get_random_u32_above(u32 floor) + * u32 get_random_u32_inclusive(u32 floor, u32 ceil) * u64 get_random_u64() * unsigned long get_random_long() * @@ -522,7 +524,21 @@ u32 __get_random_u32_below(u32 ceil) * of `-ceil % ceil` is analogous to `2^32 % ceil`, but is computable * in 32-bits. */ - u64 mult = (u64)ceil * get_random_u32(); + u32 rand = get_random_u32(); + u64 mult; + + /* + * This function is technically undefined for ceil == 0, and in fact + * for the non-underscored constant version in the header, we build bug + * on that. But for the non-constant case, it's convenient to have that + * evaluate to being a straight call to get_random_u32(), so that + * get_random_u32_inclusive() can work over its whole range without + * undefined behavior. + */ + if (unlikely(!ceil)) + return rand; + + mult = (u64)ceil * rand; if (unlikely((u32)mult < ceil)) { u32 bound = -ceil % ceil; while (unlikely((u32)mult < bound)) |