Michal Kubecek 6af2a8
From: Michal Kubecek <mkubecek@suse.cz>
Michal Kubecek 6af2a8
Date: Wed, 15 Jun 2022 09:56:43 +0200
Michal Kubecek 6af2a8
Subject: kabi: return type change of secure_ipv[46]_port_ephemeral()
Michal Kubecek 6af2a8
Patch-mainline: Never, kabi workaround
Michal Kubecek 97c264
References: CVE-2022-1012 CVE-2022-32296 bsc#1199482 bsc#1200288
Michal Kubecek 6af2a8
Michal Kubecek 6af2a8
Backport of mainline commit b2d057560b81 ("secure_seq: use the 64 bits of
Michal Kubecek 6af2a8
the siphash for port offset calculation") changed the return type of
Michal Kubecek 6af2a8
secure_ipv4_port_ephemeral() and secure_ipv6_port_ephemeral() helpers from
Michal Kubecek 6af2a8
u32 to u64.
Michal Kubecek 6af2a8
Michal Kubecek 6af2a8
Technically it should be sufficient to just hide the change from genksyms
Michal Kubecek 6af2a8
as we only build 64-bit architectures where the return value is passed in
Michal Kubecek 6af2a8
the same register for both u64 and u32 (only half being used in the latter
Michal Kubecek 6af2a8
case). But let's do a proper workaround: rename the u64 returning functions
Michal Kubecek 6af2a8
and recreate the old helpers as wrappers around them.
Michal Kubecek 6af2a8
Michal Kubecek 6af2a8
Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
Michal Kubecek 6af2a8
---
Michal Kubecek 6af2a8
 include/net/secure_seq.h    |  7 +++++--
Michal Kubecek 6af2a8
 net/core/secure_seq.c       | 19 ++++++++++++++++---
Michal Kubecek 6af2a8
 net/ipv4/inet_hashtables.c  |  6 +++---
Michal Kubecek 6af2a8
 net/ipv6/inet6_hashtables.c |  6 +++---
Michal Kubecek 6af2a8
 4 files changed, 27 insertions(+), 11 deletions(-)
Michal Kubecek 6af2a8
Michal Kubecek 6af2a8
--- a/include/net/secure_seq.h
Michal Kubecek 6af2a8
+++ b/include/net/secure_seq.h
Michal Kubecek 6af2a8
@@ -3,9 +3,12 @@
Michal Kubecek 6af2a8
 
Michal Kubecek 6af2a8
 #include <linux/types.h>
Michal Kubecek 6af2a8
 
Michal Kubecek 6af2a8
-u64 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport);
Michal Kubecek 6af2a8
-u64 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
Michal Kubecek 6af2a8
+u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport);
Michal Kubecek 6af2a8
+u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
Michal Kubecek 6af2a8
 			       __be16 dport);
Michal Kubecek 6af2a8
+u64 secure_ipv4_port_ephemeral64(__be32 saddr, __be32 daddr, __be16 dport);
Michal Kubecek 6af2a8
+u64 secure_ipv6_port_ephemeral64(const __be32 *saddr, const __be32 *daddr,
Michal Kubecek 6af2a8
+				 __be16 dport);
Michal Kubecek 6af2a8
 u32 secure_tcp_seq(__be32 saddr, __be32 daddr,
Michal Kubecek 6af2a8
 		   __be16 sport, __be16 dport);
Michal Kubecek 6af2a8
 u32 secure_tcp_ts_off(__be32 saddr, __be32 daddr);
Michal Kubecek 6af2a8
--- a/net/core/secure_seq.c
Michal Kubecek 6af2a8
+++ b/net/core/secure_seq.c
Michal Kubecek f9a43f
@@ -95,8 +95,8 @@ u32 secure_tcpv6_seq(const __be32 *saddr, const __be32 *daddr,
Michal Kubecek 6af2a8
 }
Michal Kubecek 6af2a8
 EXPORT_SYMBOL(secure_tcpv6_seq);
Michal Kubecek 6af2a8
 
Michal Kubecek 6af2a8
-u64 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
Michal Kubecek 6af2a8
-			       __be16 dport)
Michal Kubecek 6af2a8
+u64 secure_ipv6_port_ephemeral64(const __be32 *saddr, const __be32 *daddr,
Michal Kubecek 6af2a8
+				 __be16 dport)
Michal Kubecek 6af2a8
 {
Michal Kubecek 6af2a8
 	const struct {
Michal Kubecek 6af2a8
 		struct in6_addr saddr;
Michal Kubecek f9a43f
@@ -113,6 +113,13 @@ u64 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
Michal Kubecek 6af2a8
 	return siphash(&combined, offsetofend(typeof(combined), dport),
Michal Kubecek 6af2a8
 		       &net_secret);
Michal Kubecek 6af2a8
 }
Michal Kubecek 6af2a8
+EXPORT_SYMBOL(secure_ipv6_port_ephemeral64);
Michal Kubecek 6af2a8
+
Michal Kubecek 6af2a8
+u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
Michal Kubecek 6af2a8
+			       __be16 dport)
Michal Kubecek 6af2a8
+{
Michal Kubecek 6af2a8
+	return (u32)secure_ipv6_port_ephemeral64(saddr, daddr, dport);
Michal Kubecek 6af2a8
+}
Michal Kubecek 6af2a8
 EXPORT_SYMBOL(secure_ipv6_port_ephemeral);
Michal Kubecek 6af2a8
 #endif
Michal Kubecek 6af2a8
 
Michal Kubecek f9a43f
@@ -145,7 +152,7 @@ u32 secure_tcp_seq(__be32 saddr, __be32 daddr,
Michal Kubecek 6af2a8
 }
Michal Kubecek 6af2a8
 EXPORT_SYMBOL_GPL(secure_tcp_seq);
Michal Kubecek 6af2a8
 
Michal Kubecek 6af2a8
-u64 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
Michal Kubecek 6af2a8
+u64 secure_ipv4_port_ephemeral64(__be32 saddr, __be32 daddr, __be16 dport)
Michal Kubecek 6af2a8
 {
Michal Kubecek 6af2a8
 	net_secret_init();
Michal Kubecek f9a43f
 	return siphash_4u32((__force u32)saddr, (__force u32)daddr,
Michal Kubecek f9a43f
@@ -153,6 +160,12 @@ u64 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
Michal Kubecek f9a43f
 			    jiffies / EPHEMERAL_PORT_SHUFFLE_PERIOD,
Michal Kubecek f9a43f
 			    &net_secret);
Michal Kubecek 6af2a8
 }
Michal Kubecek 6af2a8
+EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral64);
Michal Kubecek 6af2a8
+
Michal Kubecek 6af2a8
+u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
Michal Kubecek 6af2a8
+{
Michal Kubecek 6af2a8
+	return (u32)secure_ipv4_port_ephemeral64(saddr, daddr, dport);
Michal Kubecek 6af2a8
+}
Michal Kubecek 6af2a8
 EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral);
Michal Kubecek 6af2a8
 #endif
Michal Kubecek 6af2a8
 
Michal Kubecek 6af2a8
--- a/net/ipv4/inet_hashtables.c
Michal Kubecek 6af2a8
+++ b/net/ipv4/inet_hashtables.c
Michal Kubecek 6af2a8
@@ -396,9 +396,9 @@ static u64 inet_sk_port_offset(const struct sock *sk)
Michal Kubecek 6af2a8
 {
Michal Kubecek 6af2a8
 	const struct inet_sock *inet = inet_sk(sk);
Michal Kubecek 6af2a8
 
Michal Kubecek 6af2a8
-	return secure_ipv4_port_ephemeral(inet->inet_rcv_saddr,
Michal Kubecek 6af2a8
-					  inet->inet_daddr,
Michal Kubecek 6af2a8
-					  inet->inet_dport);
Michal Kubecek 6af2a8
+	return secure_ipv4_port_ephemeral64(inet->inet_rcv_saddr,
Michal Kubecek 6af2a8
+					    inet->inet_daddr,
Michal Kubecek 6af2a8
+					    inet->inet_dport);
Michal Kubecek 6af2a8
 }
Michal Kubecek 6af2a8
 
Michal Kubecek 6af2a8
 /* Searches for an exsiting socket in the ehash bucket list.
Michal Kubecek 6af2a8
--- a/net/ipv6/inet6_hashtables.c
Michal Kubecek 6af2a8
+++ b/net/ipv6/inet6_hashtables.c
Michal Kubecek 6af2a8
@@ -245,9 +245,9 @@ static u64 inet6_sk_port_offset(const struct sock *sk)
Michal Kubecek 6af2a8
 {
Michal Kubecek 6af2a8
 	const struct inet_sock *inet = inet_sk(sk);
Michal Kubecek 6af2a8
 
Michal Kubecek 6af2a8
-	return secure_ipv6_port_ephemeral(sk->sk_v6_rcv_saddr.s6_addr32,
Michal Kubecek 6af2a8
-					  sk->sk_v6_daddr.s6_addr32,
Michal Kubecek 6af2a8
-					  inet->inet_dport);
Michal Kubecek 6af2a8
+	return secure_ipv6_port_ephemeral64(sk->sk_v6_rcv_saddr.s6_addr32,
Michal Kubecek 6af2a8
+					    sk->sk_v6_daddr.s6_addr32,
Michal Kubecek 6af2a8
+					    inet->inet_dport);
Michal Kubecek 6af2a8
 }
Michal Kubecek 6af2a8
 
Michal Kubecek 6af2a8
 int inet6_hash_connect(struct inet_timewait_death_row *death_row,