Blob Blame History Raw
From: Michal Kubecek <mkubecek@suse.cz>
Date: Tue, 9 Jul 2019 08:45:15 +0200
Subject: kabi: handle addition of netns_ipv4::ip_id_key
Patch-mainline: Never, kabi workaround
References: CVE-2019-10638 bsc#1140575

Backport of mainline commit df453700e8d8 ("inet: switch IP ID generator to
siphash") adds new member ip_id_ikey into struct netns_ipv4 which is
embedded into kabi-protected struct net. As struct net is always allocated
by in-tree kernel code and struct netns_ipv4 is not used anywhere else, we
can move ip_id_key out of netns_ipv4 to the end of struct net itself and
hide it from genksyms.

Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
---
 include/net/net_namespace.h | 1 +
 include/net/netns/ipv4.h    | 1 -
 net/ipv4/route.c            | 7 +++----
 net/ipv6/output_core.c      | 7 +++----
 4 files changed, 7 insertions(+), 9 deletions(-)

--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -156,6 +156,7 @@ struct net {
 #ifndef __GENKSYMS__
 	int sysctl_tcp_min_snd_mss;
 	u32			hash_mix;
+	siphash_key_t		ip_id_key;
 #endif
 };
 
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -160,6 +160,5 @@ struct netns_ipv4 {
 	unsigned int	ipmr_seq;	/* protected by rtnl_mutex */
 
 	atomic_t	rt_genid;
-	siphash_key_t	ip_id_key;
 };
 #endif
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -516,14 +516,13 @@ void __ip_select_ident(struct net *net, struct iphdr *iph, int segs)
 	u32 hash, id;
 
 	/* Note the following code is not safe, but this is okay. */
-	if (unlikely(siphash_key_is_zero(&net->ipv4.ip_id_key)))
-		get_random_bytes(&net->ipv4.ip_id_key,
-				 sizeof(net->ipv4.ip_id_key));
+	if (unlikely(siphash_key_is_zero(&net->ip_id_key)))
+		get_random_bytes(&net->ip_id_key, sizeof(net->ip_id_key));
 
 	hash = siphash_3u32((__force u32)iph->daddr,
 			    (__force u32)iph->saddr,
 			    iph->protocol,
-			    &net->ipv4.ip_id_key);
+			    &net->ip_id_key);
 	id = ip_idents_reserve(hash, segs);
 	iph->id = htons(id);
 }
--- a/net/ipv6/output_core.c
+++ b/net/ipv6/output_core.c
@@ -24,11 +24,10 @@ static u32 __ipv6_select_ident(struct net *net,
 	u32 hash, id;
 
 	/* Note the following code is not safe, but this is okay. */
-	if (unlikely(siphash_key_is_zero(&net->ipv4.ip_id_key)))
-		get_random_bytes(&net->ipv4.ip_id_key,
-				 sizeof(net->ipv4.ip_id_key));
+	if (unlikely(siphash_key_is_zero(&net->ip_id_key)))
+		get_random_bytes(&net->ip_id_key, sizeof(net->ip_id_key));
 
-	hash = siphash(&combined, sizeof(combined), &net->ipv4.ip_id_key);
+	hash = siphash(&combined, sizeof(combined), &net->ip_id_key);
 
 	/* Treat id of 0 as unset and if we get 0 back from ip_idents_reserve,
 	 * set the hight order instead thus minimizing possible future