aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-10-19 19:45:46 -0400
committerDavid S. Miller <davem@davemloft.net>2013-10-19 19:45:46 -0400
commit7dcade390860712551a4feb080911d5002226188 (patch)
tree68768a3e760a90b2b13a8e7a83d573c0e63a4a35 /include/linux
parent53481da372851a5506deb5247302f75459b472b4 (diff)
parente34c9a69970d8664a36b46e6445a7cc879111cfd (diff)
Merge branch 'net_get_random_once'
Hannes Frederic Sowa says: ==================== This series implements support for delaying the initialization of secret keys, e.g. used for hashing, for as long as possible. This functionality is implemented by a new macro, net_get_random_bytes. I already used it to protect the socket hashes, the syncookie secret (most important) and the tcp_fastopen secrets. Changelog: v2) Use static_keys in net_get_random_once to have as minimal impact to the fast-path as possible. v3) added patch "static_key: WARN on usage before jump_label_init was called": Patch "x86/jump_label: expect default_nop if static_key gets enabled on boot-up" relaxes the checks for using static_key primitives before jump_label_init. So tighten them first. v4) Update changelog on the patch "static_key: WARN on usage before jump_label_init was called" Included patches: ipv4: split inet_ehashfn to hash functions per compilation unit ipv6: split inet6_ehashfn to hash functions per compilation unit static_key: WARN on usage before jump_label_init was called x86/jump_label: expect default_nop if static_key gets enabled on boot-up net: introduce new macro net_get_random_once inet: split syncookie keys for ipv4 and ipv6 and initialize with net_get_random_once inet: convert inet_ehash_secret and ipv6_hash_secret to net_get_random_once tcp: switch tcp_fastopen key generation to net_get_random_once net: switch net_secret key generation to net_get_random_once ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/jump_label.h10
-rw-r--r--include/linux/jump_label_ratelimit.h2
-rw-r--r--include/linux/net.h25
3 files changed, 37 insertions, 0 deletions
diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h
index a5079072da66..e96be7245717 100644
--- a/include/linux/jump_label.h
+++ b/include/linux/jump_label.h
@@ -48,6 +48,13 @@
48 48
49#include <linux/types.h> 49#include <linux/types.h>
50#include <linux/compiler.h> 50#include <linux/compiler.h>
51#include <linux/bug.h>
52
53extern bool static_key_initialized;
54
55#define STATIC_KEY_CHECK_USE() WARN(!static_key_initialized, \
56 "%s used before call to jump_label_init", \
57 __func__)
51 58
52#if defined(CC_HAVE_ASM_GOTO) && defined(CONFIG_JUMP_LABEL) 59#if defined(CC_HAVE_ASM_GOTO) && defined(CONFIG_JUMP_LABEL)
53 60
@@ -128,6 +135,7 @@ struct static_key {
128 135
129static __always_inline void jump_label_init(void) 136static __always_inline void jump_label_init(void)
130{ 137{
138 static_key_initialized = true;
131} 139}
132 140
133static __always_inline bool static_key_false(struct static_key *key) 141static __always_inline bool static_key_false(struct static_key *key)
@@ -146,11 +154,13 @@ static __always_inline bool static_key_true(struct static_key *key)
146 154
147static inline void static_key_slow_inc(struct static_key *key) 155static inline void static_key_slow_inc(struct static_key *key)
148{ 156{
157 STATIC_KEY_CHECK_USE();
149 atomic_inc(&key->enabled); 158 atomic_inc(&key->enabled);
150} 159}
151 160
152static inline void static_key_slow_dec(struct static_key *key) 161static inline void static_key_slow_dec(struct static_key *key)
153{ 162{
163 STATIC_KEY_CHECK_USE();
154 atomic_dec(&key->enabled); 164 atomic_dec(&key->enabled);
155} 165}
156 166
diff --git a/include/linux/jump_label_ratelimit.h b/include/linux/jump_label_ratelimit.h
index 113788389b3d..089f70f83e97 100644
--- a/include/linux/jump_label_ratelimit.h
+++ b/include/linux/jump_label_ratelimit.h
@@ -23,12 +23,14 @@ struct static_key_deferred {
23}; 23};
24static inline void static_key_slow_dec_deferred(struct static_key_deferred *key) 24static inline void static_key_slow_dec_deferred(struct static_key_deferred *key)
25{ 25{
26 STATIC_KEY_CHECK_USE();
26 static_key_slow_dec(&key->key); 27 static_key_slow_dec(&key->key);
27} 28}
28static inline void 29static inline void
29jump_label_rate_limit(struct static_key_deferred *key, 30jump_label_rate_limit(struct static_key_deferred *key,
30 unsigned long rl) 31 unsigned long rl)
31{ 32{
33 STATIC_KEY_CHECK_USE();
32} 34}
33#endif /* HAVE_JUMP_LABEL */ 35#endif /* HAVE_JUMP_LABEL */
34#endif /* _LINUX_JUMP_LABEL_RATELIMIT_H */ 36#endif /* _LINUX_JUMP_LABEL_RATELIMIT_H */
diff --git a/include/linux/net.h b/include/linux/net.h
index ca9ec8540905..a489705f6fa3 100644
--- a/include/linux/net.h
+++ b/include/linux/net.h
@@ -239,6 +239,31 @@ do { \
239#define net_random() prandom_u32() 239#define net_random() prandom_u32()
240#define net_srandom(seed) prandom_seed((__force u32)(seed)) 240#define net_srandom(seed) prandom_seed((__force u32)(seed))
241 241
242bool __net_get_random_once(void *buf, int nbytes, bool *done,
243 struct static_key *done_key);
244
245#ifdef HAVE_JUMP_LABEL
246#define ___NET_RANDOM_STATIC_KEY_INIT ((struct static_key) \
247 { .enabled = ATOMIC_INIT(0), .entries = (void *)1 })
248#else /* !HAVE_JUMP_LABEL */
249#define ___NET_RANDOM_STATIC_KEY_INIT STATIC_KEY_INIT_FALSE
250#endif /* HAVE_JUMP_LABEL */
251
252/* BE CAREFUL: this function is not interrupt safe */
253#define net_get_random_once(buf, nbytes) \
254 ({ \
255 bool ___ret = false; \
256 static bool ___done = false; \
257 static struct static_key ___done_key = \
258 ___NET_RANDOM_STATIC_KEY_INIT; \
259 if (!static_key_true(&___done_key)) \
260 ___ret = __net_get_random_once(buf, \
261 nbytes, \
262 &___done, \
263 &___done_key); \
264 ___ret; \
265 })
266
242int kernel_sendmsg(struct socket *sock, struct msghdr *msg, struct kvec *vec, 267int kernel_sendmsg(struct socket *sock, struct msghdr *msg, struct kvec *vec,
243 size_t num, size_t len); 268 size_t num, size_t len);
244int kernel_recvmsg(struct socket *sock, struct msghdr *msg, struct kvec *vec, 269int kernel_recvmsg(struct socket *sock, struct msghdr *msg, struct kvec *vec,