diff options
| author | Russell King <rmk+kernel@armlinux.org.uk> | 2017-09-09 18:34:41 +0300 |
|---|---|---|
| committer | Russell King <rmk+kernel@armlinux.org.uk> | 2017-09-09 18:34:41 +0300 |
| commit | e558bdc21ae1f0db520eccd84015e17d8a589973 (patch) | |
| tree | b436123bd52f267b8c7f361618cded3e1e4421ea /include/linux/random.h | |
| parent | 746a272e44141af24a02f6c9b0f65f4c4598ed42 (diff) | |
| parent | 9a3dc3186fc3795e076a4122da9e0258651a9631 (diff) | |
| download | linux-e558bdc21ae1f0db520eccd84015e17d8a589973.tar.xz | |
Merge branches 'fixes' and 'misc' into for-linus
Diffstat (limited to 'include/linux/random.h')
| -rw-r--r-- | include/linux/random.h | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/include/linux/random.h b/include/linux/random.h index ed5c3838780d..eafea6a09361 100644 --- a/include/linux/random.h +++ b/include/linux/random.h @@ -34,6 +34,7 @@ extern void add_input_randomness(unsigned int type, unsigned int code, extern void add_interrupt_randomness(int irq, int irq_flags) __latent_entropy; extern void get_random_bytes(void *buf, int nbytes); +extern int wait_for_random_bytes(void); extern int add_random_ready_callback(struct random_ready_callback *rdy); extern void del_random_ready_callback(struct random_ready_callback *rdy); extern void get_random_bytes_arch(void *buf, int nbytes); @@ -57,6 +58,52 @@ static inline unsigned long get_random_long(void) #endif } +/* + * On 64-bit architectures, protect against non-terminated C string overflows + * by zeroing out the first byte of the canary; this leaves 56 bits of entropy. + */ +#ifdef CONFIG_64BIT +# ifdef __LITTLE_ENDIAN +# define CANARY_MASK 0xffffffffffffff00UL +# else /* big endian, 64 bits: */ +# define CANARY_MASK 0x00ffffffffffffffUL +# endif +#else /* 32 bits: */ +# define CANARY_MASK 0xffffffffUL +#endif + +static inline unsigned long get_random_canary(void) +{ + unsigned long val = get_random_long(); + + return val & CANARY_MASK; +} + +/* Calls wait_for_random_bytes() and then calls get_random_bytes(buf, nbytes). + * Returns the result of the call to wait_for_random_bytes. */ +static inline int get_random_bytes_wait(void *buf, int nbytes) +{ + int ret = wait_for_random_bytes(); + if (unlikely(ret)) + return ret; + get_random_bytes(buf, nbytes); + return 0; +} + +#define declare_get_random_var_wait(var) \ + static inline int get_random_ ## var ## _wait(var *out) { \ + int ret = wait_for_random_bytes(); \ + if (unlikely(ret)) \ + return ret; \ + *out = get_random_ ## var(); \ + return 0; \ + } +declare_get_random_var_wait(u32) +declare_get_random_var_wait(u64) +declare_get_random_var_wait(int) +declare_get_random_var_wait(long) +#undef declare_get_random_var + unsigned long randomize_page(unsigned long start, unsigned long range); u32 prandom_u32(void); |
