aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kernel/jump_label.c25
-rw-r--r--include/linux/jump_label.h10
-rw-r--r--include/linux/jump_label_ratelimit.h2
-rw-r--r--include/linux/net.h25
-rw-r--r--include/net/inet6_hashtables.h28
-rw-r--r--include/net/inet_sock.h26
-rw-r--r--include/net/ipv6.h4
-rw-r--r--include/net/tcp.h3
-rw-r--r--init/main.c7
-rw-r--r--kernel/jump_label.c5
-rw-r--r--net/core/secure_seq.c14
-rw-r--r--net/core/utils.c48
-rw-r--r--net/ipv4/af_inet.c27
-rw-r--r--net/ipv4/inet_hashtables.c25
-rw-r--r--net/ipv4/syncookies.c15
-rw-r--r--net/ipv4/sysctl_net_ipv4.c5
-rw-r--r--net/ipv4/tcp_fastopen.c27
-rw-r--r--net/ipv4/udp.c20
-rw-r--r--net/ipv6/af_inet6.c5
-rw-r--r--net/ipv6/inet6_hashtables.c33
-rw-r--r--net/ipv6/syncookies.c12
-rw-r--r--net/ipv6/udp.c31
-rw-r--r--net/rds/connection.c12
23 files changed, 278 insertions, 131 deletions
diff --git a/arch/x86/kernel/jump_label.c b/arch/x86/kernel/jump_label.c
index ee11b7dfbfbb..26d5a55a2736 100644
--- a/arch/x86/kernel/jump_label.c
+++ b/arch/x86/kernel/jump_label.c
@@ -42,15 +42,27 @@ static void __jump_label_transform(struct jump_entry *entry,
42 int init) 42 int init)
43{ 43{
44 union jump_code_union code; 44 union jump_code_union code;
45 const unsigned char default_nop[] = { STATIC_KEY_INIT_NOP };
45 const unsigned char *ideal_nop = ideal_nops[NOP_ATOMIC5]; 46 const unsigned char *ideal_nop = ideal_nops[NOP_ATOMIC5];
46 47
47 if (type == JUMP_LABEL_ENABLE) { 48 if (type == JUMP_LABEL_ENABLE) {
48 /* 49 if (init) {
49 * We are enabling this jump label. If it is not a nop 50 /*
50 * then something must have gone wrong. 51 * Jump label is enabled for the first time.
51 */ 52 * So we expect a default_nop...
52 if (unlikely(memcmp((void *)entry->code, ideal_nop, 5) != 0)) 53 */
53 bug_at((void *)entry->code, __LINE__); 54 if (unlikely(memcmp((void *)entry->code, default_nop, 5)
55 != 0))
56 bug_at((void *)entry->code, __LINE__);
57 } else {
58 /*
59 * ...otherwise expect an ideal_nop. Otherwise
60 * something went horribly wrong.
61 */
62 if (unlikely(memcmp((void *)entry->code, ideal_nop, 5)
63 != 0))
64 bug_at((void *)entry->code, __LINE__);
65 }
54 66
55 code.jump = 0xe9; 67 code.jump = 0xe9;
56 code.offset = entry->target - 68 code.offset = entry->target -
@@ -63,7 +75,6 @@ static void __jump_label_transform(struct jump_entry *entry,
63 * are converting the default nop to the ideal nop. 75 * are converting the default nop to the ideal nop.
64 */ 76 */
65 if (init) { 77 if (init) {
66 const unsigned char default_nop[] = { STATIC_KEY_INIT_NOP };
67 if (unlikely(memcmp((void *)entry->code, default_nop, 5) != 0)) 78 if (unlikely(memcmp((void *)entry->code, default_nop, 5) != 0))
68 bug_at((void *)entry->code, __LINE__); 79 bug_at((void *)entry->code, __LINE__);
69 } else { 80 } else {
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,
diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h
index a105d1a2fc00..ae0613544308 100644
--- a/include/net/inet6_hashtables.h
+++ b/include/net/inet6_hashtables.h
@@ -28,28 +28,14 @@
28 28
29struct inet_hashinfo; 29struct inet_hashinfo;
30 30
31static inline unsigned int inet6_ehashfn(struct net *net, 31static inline unsigned int __inet6_ehashfn(const u32 lhash,
32 const struct in6_addr *laddr, const u16 lport, 32 const u16 lport,
33 const struct in6_addr *faddr, const __be16 fport) 33 const u32 fhash,
34 const __be16 fport,
35 const u32 initval)
34{ 36{
35 u32 ports = (((u32)lport) << 16) | (__force u32)fport; 37 const u32 ports = (((u32)lport) << 16) | (__force u32)fport;
36 38 return jhash_3words(lhash, fhash, ports, initval);
37 return jhash_3words((__force u32)laddr->s6_addr32[3],
38 ipv6_addr_jhash(faddr),
39 ports,
40 inet_ehash_secret + net_hash_mix(net));
41}
42
43static inline int inet6_sk_ehashfn(const struct sock *sk)
44{
45 const struct inet_sock *inet = inet_sk(sk);
46 const struct in6_addr *laddr = &sk->sk_v6_rcv_saddr;
47 const struct in6_addr *faddr = &sk->sk_v6_daddr;
48 const __u16 lport = inet->inet_num;
49 const __be16 fport = inet->inet_dport;
50 struct net *net = sock_net(sk);
51
52 return inet6_ehashfn(net, laddr, lport, faddr, fport);
53} 39}
54 40
55int __inet6_hash(struct sock *sk, struct inet_timewait_sock *twp); 41int __inet6_hash(struct sock *sk, struct inet_timewait_sock *twp);
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
index 06da91efbc83..1833c3f389ee 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -204,30 +204,16 @@ static inline void inet_sk_copy_descendant(struct sock *sk_to,
204 204
205int inet_sk_rebuild_header(struct sock *sk); 205int inet_sk_rebuild_header(struct sock *sk);
206 206
207extern u32 inet_ehash_secret; 207static inline unsigned int __inet_ehashfn(const __be32 laddr,
208extern u32 ipv6_hash_secret; 208 const __u16 lport,
209void build_ehash_secret(void); 209 const __be32 faddr,
210 210 const __be16 fport,
211static inline unsigned int inet_ehashfn(struct net *net, 211 u32 initval)
212 const __be32 laddr, const __u16 lport,
213 const __be32 faddr, const __be16 fport)
214{ 212{
215 return jhash_3words((__force __u32) laddr, 213 return jhash_3words((__force __u32) laddr,
216 (__force __u32) faddr, 214 (__force __u32) faddr,
217 ((__u32) lport) << 16 | (__force __u32)fport, 215 ((__u32) lport) << 16 | (__force __u32)fport,
218 inet_ehash_secret + net_hash_mix(net)); 216 initval);
219}
220
221static inline int inet_sk_ehashfn(const struct sock *sk)
222{
223 const struct inet_sock *inet = inet_sk(sk);
224 const __be32 laddr = inet->inet_rcv_saddr;
225 const __u16 lport = inet->inet_num;
226 const __be32 faddr = inet->inet_daddr;
227 const __be16 fport = inet->inet_dport;
228 struct net *net = sock_net(sk);
229
230 return inet_ehashfn(net, laddr, lport, faddr, fport);
231} 217}
232 218
233static inline struct request_sock *inet_reqsk_alloc(struct request_sock_ops *ops) 219static inline struct request_sock *inet_reqsk_alloc(struct request_sock_ops *ops)
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index fe1c7f6c9217..a35055f4f8da 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -539,14 +539,14 @@ static inline u32 ipv6_addr_hash(const struct in6_addr *a)
539} 539}
540 540
541/* more secured version of ipv6_addr_hash() */ 541/* more secured version of ipv6_addr_hash() */
542static inline u32 ipv6_addr_jhash(const struct in6_addr *a) 542static inline u32 __ipv6_addr_jhash(const struct in6_addr *a, const u32 initval)
543{ 543{
544 u32 v = (__force u32)a->s6_addr32[0] ^ (__force u32)a->s6_addr32[1]; 544 u32 v = (__force u32)a->s6_addr32[0] ^ (__force u32)a->s6_addr32[1];
545 545
546 return jhash_3words(v, 546 return jhash_3words(v,
547 (__force u32)a->s6_addr32[2], 547 (__force u32)a->s6_addr32[2],
548 (__force u32)a->s6_addr32[3], 548 (__force u32)a->s6_addr32[3],
549 ipv6_hash_secret); 549 initval);
550} 550}
551 551
552static inline bool ipv6_addr_loopback(const struct in6_addr *a) 552static inline bool ipv6_addr_loopback(const struct in6_addr *a)
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 372dcccfeed0..b12e29a76590 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -475,7 +475,6 @@ int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size);
475void inet_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb); 475void inet_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb);
476 476
477/* From syncookies.c */ 477/* From syncookies.c */
478extern __u32 syncookie_secret[2][16-4+SHA_DIGEST_WORDS];
479int __cookie_v4_check(const struct iphdr *iph, const struct tcphdr *th, 478int __cookie_v4_check(const struct iphdr *iph, const struct tcphdr *th,
480 u32 cookie); 479 u32 cookie);
481struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, 480struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
@@ -1323,7 +1322,7 @@ extern struct tcp_fastopen_context __rcu *tcp_fastopen_ctx;
1323int tcp_fastopen_reset_cipher(void *key, unsigned int len); 1322int tcp_fastopen_reset_cipher(void *key, unsigned int len);
1324void tcp_fastopen_cookie_gen(__be32 src, __be32 dst, 1323void tcp_fastopen_cookie_gen(__be32 src, __be32 dst,
1325 struct tcp_fastopen_cookie *foc); 1324 struct tcp_fastopen_cookie *foc);
1326 1325void tcp_fastopen_init_key_once(bool publish);
1327#define TCP_FASTOPEN_KEY_LENGTH 16 1326#define TCP_FASTOPEN_KEY_LENGTH 16
1328 1327
1329/* Fastopen key context */ 1328/* Fastopen key context */
diff --git a/init/main.c b/init/main.c
index af310afbef28..27bbec1a5b35 100644
--- a/init/main.c
+++ b/init/main.c
@@ -136,6 +136,13 @@ static char *execute_command;
136static char *ramdisk_execute_command; 136static char *ramdisk_execute_command;
137 137
138/* 138/*
139 * Used to generate warnings if static_key manipulation functions are used
140 * before jump_label_init is called.
141 */
142bool static_key_initialized __read_mostly = false;
143EXPORT_SYMBOL_GPL(static_key_initialized);
144
145/*
139 * If set, this is an indication to the drivers that reset the underlying 146 * If set, this is an indication to the drivers that reset the underlying
140 * device before going ahead with the initialization otherwise driver might 147 * device before going ahead with the initialization otherwise driver might
141 * rely on the BIOS and skip the reset operation. 148 * rely on the BIOS and skip the reset operation.
diff --git a/kernel/jump_label.c b/kernel/jump_label.c
index 297a9247a3b3..9019f15deab2 100644
--- a/kernel/jump_label.c
+++ b/kernel/jump_label.c
@@ -58,6 +58,7 @@ static void jump_label_update(struct static_key *key, int enable);
58 58
59void static_key_slow_inc(struct static_key *key) 59void static_key_slow_inc(struct static_key *key)
60{ 60{
61 STATIC_KEY_CHECK_USE();
61 if (atomic_inc_not_zero(&key->enabled)) 62 if (atomic_inc_not_zero(&key->enabled))
62 return; 63 return;
63 64
@@ -103,12 +104,14 @@ static void jump_label_update_timeout(struct work_struct *work)
103 104
104void static_key_slow_dec(struct static_key *key) 105void static_key_slow_dec(struct static_key *key)
105{ 106{
107 STATIC_KEY_CHECK_USE();
106 __static_key_slow_dec(key, 0, NULL); 108 __static_key_slow_dec(key, 0, NULL);
107} 109}
108EXPORT_SYMBOL_GPL(static_key_slow_dec); 110EXPORT_SYMBOL_GPL(static_key_slow_dec);
109 111
110void static_key_slow_dec_deferred(struct static_key_deferred *key) 112void static_key_slow_dec_deferred(struct static_key_deferred *key)
111{ 113{
114 STATIC_KEY_CHECK_USE();
112 __static_key_slow_dec(&key->key, key->timeout, &key->work); 115 __static_key_slow_dec(&key->key, key->timeout, &key->work);
113} 116}
114EXPORT_SYMBOL_GPL(static_key_slow_dec_deferred); 117EXPORT_SYMBOL_GPL(static_key_slow_dec_deferred);
@@ -116,6 +119,7 @@ EXPORT_SYMBOL_GPL(static_key_slow_dec_deferred);
116void jump_label_rate_limit(struct static_key_deferred *key, 119void jump_label_rate_limit(struct static_key_deferred *key,
117 unsigned long rl) 120 unsigned long rl)
118{ 121{
122 STATIC_KEY_CHECK_USE();
119 key->timeout = rl; 123 key->timeout = rl;
120 INIT_DELAYED_WORK(&key->work, jump_label_update_timeout); 124 INIT_DELAYED_WORK(&key->work, jump_label_update_timeout);
121} 125}
@@ -212,6 +216,7 @@ void __init jump_label_init(void)
212 key->next = NULL; 216 key->next = NULL;
213#endif 217#endif
214 } 218 }
219 static_key_initialized = true;
215 jump_label_unlock(); 220 jump_label_unlock();
216} 221}
217 222
diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c
index 3f1ec1586ae1..b02fd16b8942 100644
--- a/net/core/secure_seq.c
+++ b/net/core/secure_seq.c
@@ -7,6 +7,7 @@
7#include <linux/hrtimer.h> 7#include <linux/hrtimer.h>
8#include <linux/ktime.h> 8#include <linux/ktime.h>
9#include <linux/string.h> 9#include <linux/string.h>
10#include <linux/net.h>
10 11
11#include <net/secure_seq.h> 12#include <net/secure_seq.h>
12 13
@@ -16,18 +17,7 @@ static u32 net_secret[NET_SECRET_SIZE] ____cacheline_aligned;
16 17
17static void net_secret_init(void) 18static void net_secret_init(void)
18{ 19{
19 u32 tmp; 20 net_get_random_once(net_secret, sizeof(net_secret));
20 int i;
21
22 if (likely(net_secret[0]))
23 return;
24
25 for (i = NET_SECRET_SIZE; i > 0;) {
26 do {
27 get_random_bytes(&tmp, sizeof(tmp));
28 } while (!tmp);
29 cmpxchg(&net_secret[--i], 0, tmp);
30 }
31} 21}
32 22
33#ifdef CONFIG_INET 23#ifdef CONFIG_INET
diff --git a/net/core/utils.c b/net/core/utils.c
index aa88e23fc87a..bf09371e19b1 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -338,3 +338,51 @@ void inet_proto_csum_replace16(__sum16 *sum, struct sk_buff *skb,
338 csum_unfold(*sum))); 338 csum_unfold(*sum)));
339} 339}
340EXPORT_SYMBOL(inet_proto_csum_replace16); 340EXPORT_SYMBOL(inet_proto_csum_replace16);
341
342struct __net_random_once_work {
343 struct work_struct work;
344 struct static_key *key;
345};
346
347static void __net_random_once_deferred(struct work_struct *w)
348{
349 struct __net_random_once_work *work =
350 container_of(w, struct __net_random_once_work, work);
351 if (!static_key_enabled(work->key))
352 static_key_slow_inc(work->key);
353 kfree(work);
354}
355
356static void __net_random_once_disable_jump(struct static_key *key)
357{
358 struct __net_random_once_work *w;
359
360 w = kmalloc(sizeof(*w), GFP_ATOMIC);
361 if (!w)
362 return;
363
364 INIT_WORK(&w->work, __net_random_once_deferred);
365 w->key = key;
366 schedule_work(&w->work);
367}
368
369bool __net_get_random_once(void *buf, int nbytes, bool *done,
370 struct static_key *done_key)
371{
372 static DEFINE_SPINLOCK(lock);
373
374 spin_lock_bh(&lock);
375 if (*done) {
376 spin_unlock_bh(&lock);
377 return false;
378 }
379
380 get_random_bytes(buf, nbytes);
381 *done = true;
382 spin_unlock_bh(&lock);
383
384 __net_random_once_disable_jump(done_key);
385
386 return true;
387}
388EXPORT_SYMBOL(__net_get_random_once);
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 4049906010f7..9433a6186f54 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -245,29 +245,6 @@ out:
245} 245}
246EXPORT_SYMBOL(inet_listen); 246EXPORT_SYMBOL(inet_listen);
247 247
248u32 inet_ehash_secret __read_mostly;
249EXPORT_SYMBOL(inet_ehash_secret);
250
251u32 ipv6_hash_secret __read_mostly;
252EXPORT_SYMBOL(ipv6_hash_secret);
253
254/*
255 * inet_ehash_secret must be set exactly once, and to a non nul value
256 * ipv6_hash_secret must be set exactly once.
257 */
258void build_ehash_secret(void)
259{
260 u32 rnd;
261
262 do {
263 get_random_bytes(&rnd, sizeof(rnd));
264 } while (rnd == 0);
265
266 if (cmpxchg(&inet_ehash_secret, 0, rnd) == 0)
267 get_random_bytes(&ipv6_hash_secret, sizeof(ipv6_hash_secret));
268}
269EXPORT_SYMBOL(build_ehash_secret);
270
271/* 248/*
272 * Create an inet socket. 249 * Create an inet socket.
273 */ 250 */
@@ -284,10 +261,6 @@ static int inet_create(struct net *net, struct socket *sock, int protocol,
284 int try_loading_module = 0; 261 int try_loading_module = 0;
285 int err; 262 int err;
286 263
287 if (unlikely(!inet_ehash_secret))
288 if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM)
289 build_ehash_secret();
290
291 sock->state = SS_UNCONNECTED; 264 sock->state = SS_UNCONNECTED;
292 265
293 /* Look for the requested type/protocol pair. */ 266 /* Look for the requested type/protocol pair. */
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index a4b66bbe4f21..8b9cf279450d 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -24,6 +24,31 @@
24#include <net/secure_seq.h> 24#include <net/secure_seq.h>
25#include <net/ip.h> 25#include <net/ip.h>
26 26
27static unsigned int inet_ehashfn(struct net *net, const __be32 laddr,
28 const __u16 lport, const __be32 faddr,
29 const __be16 fport)
30{
31 static u32 inet_ehash_secret __read_mostly;
32
33 net_get_random_once(&inet_ehash_secret, sizeof(inet_ehash_secret));
34
35 return __inet_ehashfn(laddr, lport, faddr, fport,
36 inet_ehash_secret + net_hash_mix(net));
37}
38
39
40static unsigned int inet_sk_ehashfn(const struct sock *sk)
41{
42 const struct inet_sock *inet = inet_sk(sk);
43 const __be32 laddr = inet->inet_rcv_saddr;
44 const __u16 lport = inet->inet_num;
45 const __be32 faddr = inet->inet_daddr;
46 const __be16 fport = inet->inet_dport;
47 struct net *net = sock_net(sk);
48
49 return inet_ehashfn(net, laddr, lport, faddr, fport);
50}
51
27/* 52/*
28 * Allocate and initialize a new local port bind bucket. 53 * Allocate and initialize a new local port bind bucket.
29 * The bindhash mutex for snum's hash chain must be held here. 54 * The bindhash mutex for snum's hash chain must be held here.
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index 3b64c59b4109..b95331e6c077 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -25,15 +25,7 @@
25 25
26extern int sysctl_tcp_syncookies; 26extern int sysctl_tcp_syncookies;
27 27
28__u32 syncookie_secret[2][16-4+SHA_DIGEST_WORDS]; 28static u32 syncookie_secret[2][16-4+SHA_DIGEST_WORDS];
29EXPORT_SYMBOL(syncookie_secret);
30
31static __init int init_syncookies(void)
32{
33 get_random_bytes(syncookie_secret, sizeof(syncookie_secret));
34 return 0;
35}
36__initcall(init_syncookies);
37 29
38#define COOKIEBITS 24 /* Upper bits store count */ 30#define COOKIEBITS 24 /* Upper bits store count */
39#define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1) 31#define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1)
@@ -44,8 +36,11 @@ static DEFINE_PER_CPU(__u32 [16 + 5 + SHA_WORKSPACE_WORDS],
44static u32 cookie_hash(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport, 36static u32 cookie_hash(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport,
45 u32 count, int c) 37 u32 count, int c)
46{ 38{
47 __u32 *tmp = __get_cpu_var(ipv4_cookie_scratch); 39 __u32 *tmp;
40
41 net_get_random_once(syncookie_secret, sizeof(syncookie_secret));
48 42
43 tmp = __get_cpu_var(ipv4_cookie_scratch);
49 memcpy(tmp + 4, syncookie_secret[c], sizeof(syncookie_secret[c])); 44 memcpy(tmp + 4, syncookie_secret[c], sizeof(syncookie_secret[c]));
50 tmp[0] = (__force u32)saddr; 45 tmp[0] = (__force u32)saddr;
51 tmp[1] = (__force u32)daddr; 46 tmp[1] = (__force u32)daddr;
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index c08f096d46b5..4b161d5aba0b 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -274,6 +274,11 @@ static int proc_tcp_fastopen_key(struct ctl_table *ctl, int write,
274 ret = -EINVAL; 274 ret = -EINVAL;
275 goto bad_key; 275 goto bad_key;
276 } 276 }
277 /* Generate a dummy secret but don't publish it. This
278 * is needed so we don't regenerate a new key on the
279 * first invocation of tcp_fastopen_cookie_gen
280 */
281 tcp_fastopen_init_key_once(false);
277 tcp_fastopen_reset_cipher(user_key, TCP_FASTOPEN_KEY_LENGTH); 282 tcp_fastopen_reset_cipher(user_key, TCP_FASTOPEN_KEY_LENGTH);
278 } 283 }
279 284
diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c
index ab7bd35bb312..766032b4a6c3 100644
--- a/net/ipv4/tcp_fastopen.c
+++ b/net/ipv4/tcp_fastopen.c
@@ -14,6 +14,20 @@ struct tcp_fastopen_context __rcu *tcp_fastopen_ctx;
14 14
15static DEFINE_SPINLOCK(tcp_fastopen_ctx_lock); 15static DEFINE_SPINLOCK(tcp_fastopen_ctx_lock);
16 16
17void tcp_fastopen_init_key_once(bool publish)
18{
19 static u8 key[TCP_FASTOPEN_KEY_LENGTH];
20
21 /* tcp_fastopen_reset_cipher publishes the new context
22 * atomically, so we allow this race happening here.
23 *
24 * All call sites of tcp_fastopen_cookie_gen also check
25 * for a valid cookie, so this is an acceptable risk.
26 */
27 if (net_get_random_once(key, sizeof(key)) && publish)
28 tcp_fastopen_reset_cipher(key, sizeof(key));
29}
30
17static void tcp_fastopen_ctx_free(struct rcu_head *head) 31static void tcp_fastopen_ctx_free(struct rcu_head *head)
18{ 32{
19 struct tcp_fastopen_context *ctx = 33 struct tcp_fastopen_context *ctx =
@@ -70,6 +84,8 @@ void tcp_fastopen_cookie_gen(__be32 src, __be32 dst,
70 __be32 path[4] = { src, dst, 0, 0 }; 84 __be32 path[4] = { src, dst, 0, 0 };
71 struct tcp_fastopen_context *ctx; 85 struct tcp_fastopen_context *ctx;
72 86
87 tcp_fastopen_init_key_once(true);
88
73 rcu_read_lock(); 89 rcu_read_lock();
74 ctx = rcu_dereference(tcp_fastopen_ctx); 90 ctx = rcu_dereference(tcp_fastopen_ctx);
75 if (ctx) { 91 if (ctx) {
@@ -78,14 +94,3 @@ void tcp_fastopen_cookie_gen(__be32 src, __be32 dst,
78 } 94 }
79 rcu_read_unlock(); 95 rcu_read_unlock();
80} 96}
81
82static int __init tcp_fastopen_init(void)
83{
84 __u8 key[TCP_FASTOPEN_KEY_LENGTH];
85
86 get_random_bytes(key, sizeof(key));
87 tcp_fastopen_reset_cipher(key, sizeof(key));
88 return 0;
89}
90
91late_initcall(tcp_fastopen_init);
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 9f27bb800607..89909dd730dd 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -407,6 +407,18 @@ static inline int compute_score2(struct sock *sk, struct net *net,
407 return score; 407 return score;
408} 408}
409 409
410static unsigned int udp_ehashfn(struct net *net, const __be32 laddr,
411 const __u16 lport, const __be32 faddr,
412 const __be16 fport)
413{
414 static u32 udp_ehash_secret __read_mostly;
415
416 net_get_random_once(&udp_ehash_secret, sizeof(udp_ehash_secret));
417
418 return __inet_ehashfn(laddr, lport, faddr, fport,
419 udp_ehash_secret + net_hash_mix(net));
420}
421
410 422
411/* called with read_rcu_lock() */ 423/* called with read_rcu_lock() */
412static struct sock *udp4_lib_lookup2(struct net *net, 424static struct sock *udp4_lib_lookup2(struct net *net,
@@ -430,8 +442,8 @@ begin:
430 badness = score; 442 badness = score;
431 reuseport = sk->sk_reuseport; 443 reuseport = sk->sk_reuseport;
432 if (reuseport) { 444 if (reuseport) {
433 hash = inet_ehashfn(net, daddr, hnum, 445 hash = udp_ehashfn(net, daddr, hnum,
434 saddr, sport); 446 saddr, sport);
435 matches = 1; 447 matches = 1;
436 } 448 }
437 } else if (score == badness && reuseport) { 449 } else if (score == badness && reuseport) {
@@ -511,8 +523,8 @@ begin:
511 badness = score; 523 badness = score;
512 reuseport = sk->sk_reuseport; 524 reuseport = sk->sk_reuseport;
513 if (reuseport) { 525 if (reuseport) {
514 hash = inet_ehashfn(net, daddr, hnum, 526 hash = udp_ehashfn(net, daddr, hnum,
515 saddr, sport); 527 saddr, sport);
516 matches = 1; 528 matches = 1;
517 } 529 }
518 } else if (score == badness && reuseport) { 530 } else if (score == badness && reuseport) {
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index a2cb07cd3850..20af1fb81c83 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -110,11 +110,6 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol,
110 int try_loading_module = 0; 110 int try_loading_module = 0;
111 int err; 111 int err;
112 112
113 if (sock->type != SOCK_RAW &&
114 sock->type != SOCK_DGRAM &&
115 !inet_ehash_secret)
116 build_ehash_secret();
117
118 /* Look for the requested type/protocol pair. */ 113 /* Look for the requested type/protocol pair. */
119lookup_protocol: 114lookup_protocol:
120 err = -ESOCKTNOSUPPORT; 115 err = -ESOCKTNOSUPPORT;
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index 842d833dfc18..262e13c02ec2 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -23,6 +23,39 @@
23#include <net/secure_seq.h> 23#include <net/secure_seq.h>
24#include <net/ip.h> 24#include <net/ip.h>
25 25
26static unsigned int inet6_ehashfn(struct net *net,
27 const struct in6_addr *laddr,
28 const u16 lport,
29 const struct in6_addr *faddr,
30 const __be16 fport)
31{
32 static u32 inet6_ehash_secret __read_mostly;
33 static u32 ipv6_hash_secret __read_mostly;
34
35 u32 lhash, fhash;
36
37 net_get_random_once(&inet6_ehash_secret, sizeof(inet6_ehash_secret));
38 net_get_random_once(&ipv6_hash_secret, sizeof(ipv6_hash_secret));
39
40 lhash = (__force u32)laddr->s6_addr32[3];
41 fhash = __ipv6_addr_jhash(faddr, ipv6_hash_secret);
42
43 return __inet6_ehashfn(lhash, lport, fhash, fport,
44 inet6_ehash_secret + net_hash_mix(net));
45}
46
47static int inet6_sk_ehashfn(const struct sock *sk)
48{
49 const struct inet_sock *inet = inet_sk(sk);
50 const struct in6_addr *laddr = &sk->sk_v6_rcv_saddr;
51 const struct in6_addr *faddr = &sk->sk_v6_daddr;
52 const __u16 lport = inet->inet_num;
53 const __be16 fport = inet->inet_dport;
54 struct net *net = sock_net(sk);
55
56 return inet6_ehashfn(net, laddr, lport, faddr, fport);
57}
58
26int __inet6_hash(struct sock *sk, struct inet_timewait_sock *tw) 59int __inet6_hash(struct sock *sk, struct inet_timewait_sock *tw)
27{ 60{
28 struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo; 61 struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo;
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index d04d3f1dd9b7..535a3ad262f1 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -24,6 +24,8 @@
24#define COOKIEBITS 24 /* Upper bits store count */ 24#define COOKIEBITS 24 /* Upper bits store count */
25#define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1) 25#define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1)
26 26
27static u32 syncookie6_secret[2][16-4+SHA_DIGEST_WORDS];
28
27/* RFC 2460, Section 8.3: 29/* RFC 2460, Section 8.3:
28 * [ipv6 tcp] MSS must be computed as the maximum packet size minus 60 [..] 30 * [ipv6 tcp] MSS must be computed as the maximum packet size minus 60 [..]
29 * 31 *
@@ -61,14 +63,18 @@ static DEFINE_PER_CPU(__u32 [16 + 5 + SHA_WORKSPACE_WORDS],
61static u32 cookie_hash(const struct in6_addr *saddr, const struct in6_addr *daddr, 63static u32 cookie_hash(const struct in6_addr *saddr, const struct in6_addr *daddr,
62 __be16 sport, __be16 dport, u32 count, int c) 64 __be16 sport, __be16 dport, u32 count, int c)
63{ 65{
64 __u32 *tmp = __get_cpu_var(ipv6_cookie_scratch); 66 __u32 *tmp;
67
68 net_get_random_once(syncookie6_secret, sizeof(syncookie6_secret));
69
70 tmp = __get_cpu_var(ipv6_cookie_scratch);
65 71
66 /* 72 /*
67 * we have 320 bits of information to hash, copy in the remaining 73 * we have 320 bits of information to hash, copy in the remaining
68 * 192 bits required for sha_transform, from the syncookie_secret 74 * 192 bits required for sha_transform, from the syncookie6_secret
69 * and overwrite the digest with the secret 75 * and overwrite the digest with the secret
70 */ 76 */
71 memcpy(tmp + 10, syncookie_secret[c], 44); 77 memcpy(tmp + 10, syncookie6_secret[c], 44);
72 memcpy(tmp, saddr, 16); 78 memcpy(tmp, saddr, 16);
73 memcpy(tmp + 4, daddr, 16); 79 memcpy(tmp + 4, daddr, 16);
74 tmp[8] = ((__force u32)sport << 16) + (__force u32)dport; 80 tmp[8] = ((__force u32)sport << 16) + (__force u32)dport;
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index b496de19a341..44fc4e3d661f 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -53,6 +53,29 @@
53#include <trace/events/skb.h> 53#include <trace/events/skb.h>
54#include "udp_impl.h" 54#include "udp_impl.h"
55 55
56static unsigned int udp6_ehashfn(struct net *net,
57 const struct in6_addr *laddr,
58 const u16 lport,
59 const struct in6_addr *faddr,
60 const __be16 fport)
61{
62 static u32 udp6_ehash_secret __read_mostly;
63 static u32 udp_ipv6_hash_secret __read_mostly;
64
65 u32 lhash, fhash;
66
67 net_get_random_once(&udp6_ehash_secret,
68 sizeof(udp6_ehash_secret));
69 net_get_random_once(&udp_ipv6_hash_secret,
70 sizeof(udp_ipv6_hash_secret));
71
72 lhash = (__force u32)laddr->s6_addr32[3];
73 fhash = __ipv6_addr_jhash(faddr, udp_ipv6_hash_secret);
74
75 return __inet6_ehashfn(lhash, lport, fhash, fport,
76 udp_ipv6_hash_secret + net_hash_mix(net));
77}
78
56int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2) 79int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2)
57{ 80{
58 const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2); 81 const struct in6_addr *sk2_rcv_saddr6 = inet6_rcv_saddr(sk2);
@@ -214,8 +237,8 @@ begin:
214 badness = score; 237 badness = score;
215 reuseport = sk->sk_reuseport; 238 reuseport = sk->sk_reuseport;
216 if (reuseport) { 239 if (reuseport) {
217 hash = inet6_ehashfn(net, daddr, hnum, 240 hash = udp6_ehashfn(net, daddr, hnum,
218 saddr, sport); 241 saddr, sport);
219 matches = 1; 242 matches = 1;
220 } else if (score == SCORE2_MAX) 243 } else if (score == SCORE2_MAX)
221 goto exact_match; 244 goto exact_match;
@@ -295,8 +318,8 @@ begin:
295 badness = score; 318 badness = score;
296 reuseport = sk->sk_reuseport; 319 reuseport = sk->sk_reuseport;
297 if (reuseport) { 320 if (reuseport) {
298 hash = inet6_ehashfn(net, daddr, hnum, 321 hash = udp6_ehashfn(net, daddr, hnum,
299 saddr, sport); 322 saddr, sport);
300 matches = 1; 323 matches = 1;
301 } 324 }
302 } else if (score == badness && reuseport) { 325 } else if (score == badness && reuseport) {
diff --git a/net/rds/connection.c b/net/rds/connection.c
index 642ad42c416b..378c3a6acf84 100644
--- a/net/rds/connection.c
+++ b/net/rds/connection.c
@@ -51,10 +51,16 @@ static struct kmem_cache *rds_conn_slab;
51 51
52static struct hlist_head *rds_conn_bucket(__be32 laddr, __be32 faddr) 52static struct hlist_head *rds_conn_bucket(__be32 laddr, __be32 faddr)
53{ 53{
54 static u32 rds_hash_secret __read_mostly;
55
56 unsigned long hash;
57
58 net_get_random_once(&rds_hash_secret, sizeof(rds_hash_secret));
59
54 /* Pass NULL, don't need struct net for hash */ 60 /* Pass NULL, don't need struct net for hash */
55 unsigned long hash = inet_ehashfn(NULL, 61 hash = __inet_ehashfn(be32_to_cpu(laddr), 0,
56 be32_to_cpu(laddr), 0, 62 be32_to_cpu(faddr), 0,
57 be32_to_cpu(faddr), 0); 63 rds_hash_secret);
58 return &rds_conn_hash[hash & RDS_CONNECTION_HASH_MASK]; 64 return &rds_conn_hash[hash & RDS_CONNECTION_HASH_MASK];
59} 65}
60 66