inet: split syncookie keys for ipv4 and ipv6 and initialize with net_get_random_once
authorHannes Frederic Sowa <hannes@stressinduktion.org>
Sat, 19 Oct 2013 19:48:56 +0000 (21:48 +0200)
committerDavid S. Miller <davem@davemloft.net>
Sat, 19 Oct 2013 23:45:35 +0000 (19:45 -0400)
This patch splits the secret key for syncookies for ipv4 and ipv6 and
initializes them with net_get_random_once. This change was the reason I
did this series. I think the initialization of the syncookie_secret is
way to early.

Cc: Florian Westphal <fw@strlen.de>
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>
include/net/tcp.h
net/ipv4/syncookies.c
net/ipv6/syncookies.c

index 372dcccfeed0fdb320b3aa8bcb7de8112f235093..f30326f1c92b4d6235ae539c3848106c27a3f21c 100644 (file)
@@ -475,7 +475,6 @@ int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size);
 void inet_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb);
 
 /* From syncookies.c */
-extern __u32 syncookie_secret[2][16-4+SHA_DIGEST_WORDS];
 int __cookie_v4_check(const struct iphdr *iph, const struct tcphdr *th,
                      u32 cookie);
 struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
index 3b64c59b41099d4c0899d3ffc638740edfaec5e0..b95331e6c077cea0ff215702087fa14acd00abaf 100644 (file)
 
 extern int sysctl_tcp_syncookies;
 
-__u32 syncookie_secret[2][16-4+SHA_DIGEST_WORDS];
-EXPORT_SYMBOL(syncookie_secret);
-
-static __init int init_syncookies(void)
-{
-       get_random_bytes(syncookie_secret, sizeof(syncookie_secret));
-       return 0;
-}
-__initcall(init_syncookies);
+static u32 syncookie_secret[2][16-4+SHA_DIGEST_WORDS];
 
 #define COOKIEBITS 24  /* Upper bits store count */
 #define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1)
@@ -44,8 +36,11 @@ static DEFINE_PER_CPU(__u32 [16 + 5 + SHA_WORKSPACE_WORDS],
 static u32 cookie_hash(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport,
                       u32 count, int c)
 {
-       __u32 *tmp = __get_cpu_var(ipv4_cookie_scratch);
+       __u32 *tmp;
+
+       net_get_random_once(syncookie_secret, sizeof(syncookie_secret));
 
+       tmp  = __get_cpu_var(ipv4_cookie_scratch);
        memcpy(tmp + 4, syncookie_secret[c], sizeof(syncookie_secret[c]));
        tmp[0] = (__force u32)saddr;
        tmp[1] = (__force u32)daddr;
index d04d3f1dd9b7172e8699bbe47db832a6454f985e..535a3ad262f18d7dcc04586fc55c3f0e9d4afe8b 100644 (file)
@@ -24,6 +24,8 @@
 #define COOKIEBITS 24  /* Upper bits store count */
 #define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1)
 
+static u32 syncookie6_secret[2][16-4+SHA_DIGEST_WORDS];
+
 /* RFC 2460, Section 8.3:
  * [ipv6 tcp] MSS must be computed as the maximum packet size minus 60 [..]
  *
@@ -61,14 +63,18 @@ static DEFINE_PER_CPU(__u32 [16 + 5 + SHA_WORKSPACE_WORDS],
 static u32 cookie_hash(const struct in6_addr *saddr, const struct in6_addr *daddr,
                       __be16 sport, __be16 dport, u32 count, int c)
 {
-       __u32 *tmp = __get_cpu_var(ipv6_cookie_scratch);
+       __u32 *tmp;
+
+       net_get_random_once(syncookie6_secret, sizeof(syncookie6_secret));
+
+       tmp  = __get_cpu_var(ipv6_cookie_scratch);
 
        /*
         * we have 320 bits of information to hash, copy in the remaining
-        * 192 bits required for sha_transform, from the syncookie_secret
+        * 192 bits required for sha_transform, from the syncookie6_secret
         * and overwrite the digest with the secret
         */
-       memcpy(tmp + 10, syncookie_secret[c], 44);
+       memcpy(tmp + 10, syncookie6_secret[c], 44);
        memcpy(tmp, saddr, 16);
        memcpy(tmp + 4, daddr, 16);
        tmp[8] = ((__force u32)sport << 16) + (__force u32)dport;