diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2018-08-24 10:59:37 -0700 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2018-08-28 23:20:13 -0600 |
commit | 9a5f03e08aeda3af222c895f8859e35b483e046f (patch) | |
tree | bf6763c4d215bd3e5f3281fa1d422c6c7b2fb4e1 /src/compat | |
parent | a18329341368fc9b9b19055736aa9731bf81ec97 (diff) |
compat: rng_is_initialized made it into 4.19
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'src/compat')
-rw-r--r-- | src/compat/compat.h | 106 |
1 files changed, 53 insertions, 53 deletions
diff --git a/src/compat/compat.h b/src/compat/compat.h index c6e1e50..9e92236 100644 --- a/src/compat/compat.h +++ b/src/compat/compat.h @@ -318,6 +318,59 @@ static inline int wait_for_random_bytes(void) return 0; } #endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 19, 0) && LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) +#include <linux/random.h> +#include <linux/slab.h> +struct rng_is_initialized_callback { + struct random_ready_callback cb; + atomic_t *rng_state; +}; +static inline void rng_is_initialized_callback(struct random_ready_callback *cb) +{ + struct rng_is_initialized_callback *rdy = container_of(cb, struct rng_is_initialized_callback, cb); + atomic_set(rdy->rng_state, 2); + kfree(rdy); +} +static inline bool rng_is_initialized(void) +{ + static atomic_t rng_state = ATOMIC_INIT(0); + + if (atomic_read(&rng_state) == 2) + return true; + + if (atomic_cmpxchg(&rng_state, 0, 1) == 0) { + int ret; + struct rng_is_initialized_callback *rdy = kmalloc(sizeof(*rdy), GFP_ATOMIC); + if (!rdy) { + atomic_set(&rng_state, 0); + return false; + } + rdy->cb.owner = THIS_MODULE; + rdy->cb.func = rng_is_initialized_callback; + rdy->rng_state = &rng_state; + ret = add_random_ready_callback(&rdy->cb); + if (ret) + kfree(rdy); + if (ret == -EALREADY) { + atomic_set(&rng_state, 2); + return true; + } else if (ret) + atomic_set(&rng_state, 0); + return false; + } + return false; +} +#elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) +/* This is a disaster. Without this API, we really have no way of + * knowing if it's initialized. We just return that it has and hope + * for the best... */ +static inline bool rng_is_initialized(void) +{ + return true; +} +#endif + #if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0) && !defined(ISOPENSUSE15) static inline int get_random_bytes_wait(void *buf, int nbytes) { @@ -667,59 +720,6 @@ static inline void new_icmpv6_send(struct sk_buff *skb, u8 type, u8 code, __u32 #define icmpv6_send(a,b,c,d) new_icmpv6_send(a,b,c,d) #endif -/* https://lkml.kernel.org/r/20180618234347.13282-1-Jason@zx2c4.com */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0) -#include <linux/random.h> -#include <linux/slab.h> -struct rng_is_initialized_callback { - struct random_ready_callback cb; - atomic_t *rng_state; -}; -static inline void rng_is_initialized_callback(struct random_ready_callback *cb) -{ - struct rng_is_initialized_callback *rdy = container_of(cb, struct rng_is_initialized_callback, cb); - atomic_set(rdy->rng_state, 2); - kfree(rdy); -} -static inline bool rng_is_initialized(void) -{ - static atomic_t rng_state = ATOMIC_INIT(0); - - if (atomic_read(&rng_state) == 2) - return true; - - if (atomic_cmpxchg(&rng_state, 0, 1) == 0) { - int ret; - struct rng_is_initialized_callback *rdy = kmalloc(sizeof(*rdy), GFP_ATOMIC); - if (!rdy) { - atomic_set(&rng_state, 0); - return false; - } - rdy->cb.owner = THIS_MODULE; - rdy->cb.func = rng_is_initialized_callback; - rdy->rng_state = &rng_state; - ret = add_random_ready_callback(&rdy->cb); - if (ret) - kfree(rdy); - if (ret == -EALREADY) { - atomic_set(&rng_state, 2); - return true; - } else if (ret) - atomic_set(&rng_state, 0); - return false; - } - return false; -} -#else -/* This is a disaster. Without this API, we really have no way of - * knowing if it's initialized. We just return that it has and hope - * for the best... */ -static inline bool rng_is_initialized(void) -{ - return true; -} -#endif - /* PaX compatibility */ #ifdef CONSTIFY_PLUGIN #include <linux/cache.h> |