]>
Commit | Line | Data |
---|---|---|
a9fba688 SL |
1 | From 21da00dd528b93c6d3a6f107a53d3ba48a991bfe Mon Sep 17 00:00:00 2001 |
2 | From: Eric Dumazet <edumazet@google.com> | |
3 | Date: Wed, 27 Mar 2019 08:21:30 -0700 | |
4 | Subject: netns: provide pure entropy for net_hash_mix() | |
5 | ||
6 | [ Upstream commit 355b98553789b646ed97ad801a619ff898471b92 ] | |
7 | ||
8 | net_hash_mix() currently uses kernel address of a struct net, | |
9 | and is used in many places that could be used to reveal this | |
10 | address to a patient attacker, thus defeating KASLR, for | |
11 | the typical case (initial net namespace, &init_net is | |
12 | not dynamically allocated) | |
13 | ||
14 | I believe the original implementation tried to avoid spending | |
15 | too many cycles in this function, but security comes first. | |
16 | ||
17 | Also provide entropy regardless of CONFIG_NET_NS. | |
18 | ||
19 | Fixes: 0b4419162aa6 ("netns: introduce the net_hash_mix "salt" for hashes") | |
20 | Signed-off-by: Eric Dumazet <edumazet@google.com> | |
21 | Reported-by: Amit Klein <aksecurity@gmail.com> | |
22 | Reported-by: Benny Pinkas <benny@pinkas.net> | |
23 | Cc: Pavel Emelyanov <xemul@openvz.org> | |
24 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
25 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
26 | --- | |
27 | include/net/net_namespace.h | 1 + | |
28 | include/net/netns/hash.h | 10 ++-------- | |
29 | net/core/net_namespace.c | 1 + | |
30 | 3 files changed, 4 insertions(+), 8 deletions(-) | |
31 | ||
32 | diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h | |
33 | index 9b5fdc50519a..3f7b166262d7 100644 | |
34 | --- a/include/net/net_namespace.h | |
35 | +++ b/include/net/net_namespace.h | |
36 | @@ -57,6 +57,7 @@ struct net { | |
37 | */ | |
38 | spinlock_t rules_mod_lock; | |
39 | ||
40 | + u32 hash_mix; | |
41 | atomic64_t cookie_gen; | |
42 | ||
43 | struct list_head list; /* list of network namespaces */ | |
44 | diff --git a/include/net/netns/hash.h b/include/net/netns/hash.h | |
45 | index 16a842456189..d9b665151f3d 100644 | |
46 | --- a/include/net/netns/hash.h | |
47 | +++ b/include/net/netns/hash.h | |
48 | @@ -2,16 +2,10 @@ | |
49 | #ifndef __NET_NS_HASH_H__ | |
50 | #define __NET_NS_HASH_H__ | |
51 | ||
52 | -#include <asm/cache.h> | |
53 | - | |
54 | -struct net; | |
55 | +#include <net/net_namespace.h> | |
56 | ||
57 | static inline u32 net_hash_mix(const struct net *net) | |
58 | { | |
59 | -#ifdef CONFIG_NET_NS | |
60 | - return (u32)(((unsigned long)net) >> ilog2(sizeof(*net))); | |
61 | -#else | |
62 | - return 0; | |
63 | -#endif | |
64 | + return net->hash_mix; | |
65 | } | |
66 | #endif | |
67 | diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c | |
68 | index 670c84b1bfc2..7320f0844a50 100644 | |
69 | --- a/net/core/net_namespace.c | |
70 | +++ b/net/core/net_namespace.c | |
71 | @@ -304,6 +304,7 @@ static __net_init int setup_net(struct net *net, struct user_namespace *user_ns) | |
72 | ||
73 | refcount_set(&net->count, 1); | |
74 | refcount_set(&net->passive, 1); | |
75 | + get_random_bytes(&net->hash_mix, sizeof(u32)); | |
76 | net->dev_base_seq = 1; | |
77 | net->user_ns = user_ns; | |
78 | idr_init(&net->netns_ids); | |
79 | -- | |
80 | 2.19.1 | |
81 |