diff options
| author | David S. Miller <davem@davemloft.net> | 2013-10-19 19:45:46 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2013-10-19 19:45:46 -0400 |
| commit | 7dcade390860712551a4feb080911d5002226188 (patch) | |
| tree | 68768a3e760a90b2b13a8e7a83d573c0e63a4a35 /include/linux | |
| parent | 53481da372851a5506deb5247302f75459b472b4 (diff) | |
| parent | e34c9a69970d8664a36b46e6445a7cc879111cfd (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.h | 10 | ||||
| -rw-r--r-- | include/linux/jump_label_ratelimit.h | 2 | ||||
| -rw-r--r-- | include/linux/net.h | 25 |
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 | |||
| 53 | extern 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 | ||
| 129 | static __always_inline void jump_label_init(void) | 136 | static __always_inline void jump_label_init(void) |
| 130 | { | 137 | { |
| 138 | static_key_initialized = true; | ||
| 131 | } | 139 | } |
| 132 | 140 | ||
| 133 | static __always_inline bool static_key_false(struct static_key *key) | 141 | static __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 | ||
| 147 | static inline void static_key_slow_inc(struct static_key *key) | 155 | static 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 | ||
| 152 | static inline void static_key_slow_dec(struct static_key *key) | 161 | static 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 | }; |
| 24 | static inline void static_key_slow_dec_deferred(struct static_key_deferred *key) | 24 | static 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 | } |
| 28 | static inline void | 29 | static inline void |
| 29 | jump_label_rate_limit(struct static_key_deferred *key, | 30 | jump_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 | ||
| 242 | bool __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 | |||
| 242 | int kernel_sendmsg(struct socket *sock, struct msghdr *msg, struct kvec *vec, | 267 | int 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); |
| 244 | int kernel_recvmsg(struct socket *sock, struct msghdr *msg, struct kvec *vec, | 269 | int kernel_recvmsg(struct socket *sock, struct msghdr *msg, struct kvec *vec, |
