X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=drivers%2Fchar%2Frandom.c;h=d6876d50622075f1b490bf7a19831b4e8784adb6;hb=9ffc66941df278c9f4df979b6bcf6c6ddafedd16;hp=7274ae89ddb39f3450ac9f56ef64db6384330497;hpb=0766f788eb727e2e330d55d30545db65bcf2623f;p=cascardo%2Flinux.git diff --git a/drivers/char/random.c b/drivers/char/random.c index 7274ae89ddb3..d6876d506220 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -2100,23 +2100,37 @@ unsigned long get_random_long(void) } EXPORT_SYMBOL(get_random_long); -/* - * randomize_range() returns a start address such that +/** + * randomize_page - Generate a random, page aligned address + * @start: The smallest acceptable address the caller will take. + * @range: The size of the area, starting at @start, within which the + * random address must fall. + * + * If @start + @range would overflow, @range is capped. * - * [...... .....] - * start end + * NOTE: Historical use of randomize_range, which this replaces, presumed that + * @start was already page aligned. We now align it regardless. * - * a with size "len" starting at the return value is inside in the - * area defined by [start, end], but is otherwise randomized. + * Return: A page aligned address within [start, start + range). On error, + * @start is returned. */ unsigned long -randomize_range(unsigned long start, unsigned long end, unsigned long len) +randomize_page(unsigned long start, unsigned long range) { - unsigned long range = end - len - start; + if (!PAGE_ALIGNED(start)) { + range -= PAGE_ALIGN(start) - start; + start = PAGE_ALIGN(start); + } - if (end <= start + len) - return 0; - return PAGE_ALIGN(get_random_int() % range + start); + if (start > ULONG_MAX - range) + range = ULONG_MAX - start; + + range >>= PAGE_SHIFT; + + if (range == 0) + return start; + + return start + (get_random_long() % range << PAGE_SHIFT); } /* Interface for in-kernel drivers of true hardware RNGs.