X-Git-Url: https://git.karo-electronics.de/?a=blobdiff_plain;f=drivers%2Fchar%2Frandom.c;h=1ef26403bcc83f6a0c26f20d67b74e7fe6331635;hb=bb1181c9a8b46b6f10e749d9ed94480336445d7f;hp=3efb3bf0ab839578156e33907eb20c741c08155f;hpb=2161a2a644a6d33a29d68395518d103ed805758f;p=karo-tx-linux.git diff --git a/drivers/char/random.c b/drivers/char/random.c index 3efb3bf0ab83..1ef26403bcc8 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -265,7 +265,7 @@ #include #include -#include +#include #include #include #include @@ -479,8 +479,8 @@ static ssize_t _extract_entropy(struct entropy_store *r, void *buf, static void crng_reseed(struct crng_state *crng, struct entropy_store *r); static void push_to_pool(struct work_struct *work); -static __u32 input_pool_data[INPUT_POOL_WORDS]; -static __u32 blocking_pool_data[OUTPUT_POOL_WORDS]; +static __u32 input_pool_data[INPUT_POOL_WORDS] __latent_entropy; +static __u32 blocking_pool_data[OUTPUT_POOL_WORDS] __latent_entropy; static struct entropy_store input_pool = { .poolinfo = &poolinfo_table[0], @@ -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.