Commit 9a3bab6b authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller
Browse files

net: net_secret should not depend on TCP



A host might need net_secret[] and never open a single socket.

Problem added in commit aebda156
("net: defer net_secret[] initialization")

Based on prior patch from Hannes Frederic Sowa.

Reported-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Acked-by: default avatarHannes Frederic Sowa <hannes@strressinduktion.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 50624c93
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -3,7 +3,6 @@

#include <linux/types.h>

extern void net_secret_init(void);
extern __u32 secure_ip_id(__be32 daddr);
extern __u32 secure_ipv6_id(const __be32 daddr[4]);
extern u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport);
+24 −3
Original line number Diff line number Diff line
@@ -10,11 +10,24 @@

#include <net/secure_seq.h>

static u32 net_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned;
#define NET_SECRET_SIZE (MD5_MESSAGE_BYTES / 4)

void net_secret_init(void)
static u32 net_secret[NET_SECRET_SIZE] ____cacheline_aligned;

static void net_secret_init(void)
{
	get_random_bytes(net_secret, sizeof(net_secret));
	u32 tmp;
	int i;

	if (likely(net_secret[0]))
		return;

	for (i = NET_SECRET_SIZE; i > 0;) {
		do {
			get_random_bytes(&tmp, sizeof(tmp));
		} while (!tmp);
		cmpxchg(&net_secret[--i], 0, tmp);
	}
}

#ifdef CONFIG_INET
@@ -42,6 +55,7 @@ __u32 secure_tcpv6_sequence_number(const __be32 *saddr, const __be32 *daddr,
	u32 hash[MD5_DIGEST_WORDS];
	u32 i;

	net_secret_init();
	memcpy(hash, saddr, 16);
	for (i = 0; i < 4; i++)
		secret[i] = net_secret[i] + (__force u32)daddr[i];
@@ -63,6 +77,7 @@ u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
	u32 hash[MD5_DIGEST_WORDS];
	u32 i;

	net_secret_init();
	memcpy(hash, saddr, 16);
	for (i = 0; i < 4; i++)
		secret[i] = net_secret[i] + (__force u32) daddr[i];
@@ -82,6 +97,7 @@ __u32 secure_ip_id(__be32 daddr)
{
	u32 hash[MD5_DIGEST_WORDS];

	net_secret_init();
	hash[0] = (__force __u32) daddr;
	hash[1] = net_secret[13];
	hash[2] = net_secret[14];
@@ -96,6 +112,7 @@ __u32 secure_ipv6_id(const __be32 daddr[4])
{
	__u32 hash[4];

	net_secret_init();
	memcpy(hash, daddr, 16);
	md5_transform(hash, net_secret);

@@ -107,6 +124,7 @@ __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr,
{
	u32 hash[MD5_DIGEST_WORDS];

	net_secret_init();
	hash[0] = (__force u32)saddr;
	hash[1] = (__force u32)daddr;
	hash[2] = ((__force u16)sport << 16) + (__force u16)dport;
@@ -121,6 +139,7 @@ u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
{
	u32 hash[MD5_DIGEST_WORDS];

	net_secret_init();
	hash[0] = (__force u32)saddr;
	hash[1] = (__force u32)daddr;
	hash[2] = (__force u32)dport ^ net_secret[14];
@@ -140,6 +159,7 @@ u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr,
	u32 hash[MD5_DIGEST_WORDS];
	u64 seq;

	net_secret_init();
	hash[0] = (__force u32)saddr;
	hash[1] = (__force u32)daddr;
	hash[2] = ((__force u16)sport << 16) + (__force u16)dport;
@@ -164,6 +184,7 @@ u64 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr,
	u64 seq;
	u32 i;

	net_secret_init();
	memcpy(hash, saddr, 16);
	for (i = 0; i < 4; i++)
		secret[i] = net_secret[i] + daddr[i];
+1 −3
Original line number Diff line number Diff line
@@ -263,10 +263,8 @@ void build_ehash_secret(void)
		get_random_bytes(&rnd, sizeof(rnd));
	} while (rnd == 0);

	if (cmpxchg(&inet_ehash_secret, 0, rnd) == 0) {
	if (cmpxchg(&inet_ehash_secret, 0, rnd) == 0)
		get_random_bytes(&ipv6_hash_secret, sizeof(ipv6_hash_secret));
		net_secret_init();
	}
}
EXPORT_SYMBOL(build_ehash_secret);