Skip to content

Commit 222e83d

Browse files
strssndktndavem330
authored andcommitted
tcp: switch tcp_fastopen key generation to net_get_random_once
Changed key initialization of tcp_fastopen cookies to net_get_random_once. If the user sets a custom key net_get_random_once must be called at least once to ensure we don't overwrite the user provided key when the first cookie is generated later on. Cc: Yuchung Cheng <ycheng@google.com> Cc: Eric Dumazet <edumazet@google.com> Cc: "David S. Miller" <davem@davemloft.net> Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 1bbdcee commit 222e83d

File tree

3 files changed

+22
-12
lines changed

3 files changed

+22
-12
lines changed

include/net/tcp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1322,7 +1322,7 @@ extern struct tcp_fastopen_context __rcu *tcp_fastopen_ctx;
13221322
int tcp_fastopen_reset_cipher(void *key, unsigned int len);
13231323
void tcp_fastopen_cookie_gen(__be32 src, __be32 dst,
13241324
struct tcp_fastopen_cookie *foc);
1325-
1325+
void tcp_fastopen_init_key_once(bool publish);
13261326
#define TCP_FASTOPEN_KEY_LENGTH 16
13271327

13281328
/* Fastopen key context */

net/ipv4/sysctl_net_ipv4.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,11 @@ static int proc_tcp_fastopen_key(struct ctl_table *ctl, int write,
274274
ret = -EINVAL;
275275
goto bad_key;
276276
}
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);
277282
tcp_fastopen_reset_cipher(user_key, TCP_FASTOPEN_KEY_LENGTH);
278283
}
279284

net/ipv4/tcp_fastopen.c

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,20 @@ struct tcp_fastopen_context __rcu *tcp_fastopen_ctx;
1414

1515
static DEFINE_SPINLOCK(tcp_fastopen_ctx_lock);
1616

17+
void 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+
1731
static void tcp_fastopen_ctx_free(struct rcu_head *head)
1832
{
1933
struct tcp_fastopen_context *ctx =
@@ -70,6 +84,8 @@ void tcp_fastopen_cookie_gen(__be32 src, __be32 dst,
7084
__be32 path[4] = { src, dst, 0, 0 };
7185
struct tcp_fastopen_context *ctx;
7286

87+
tcp_fastopen_init_key_once(true);
88+
7389
rcu_read_lock();
7490
ctx = rcu_dereference(tcp_fastopen_ctx);
7591
if (ctx) {
@@ -78,14 +94,3 @@ void tcp_fastopen_cookie_gen(__be32 src, __be32 dst,
7894
}
7995
rcu_read_unlock();
8096
}
81-
82-
static 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-
91-
late_initcall(tcp_fastopen_init);

0 commit comments

Comments
 (0)