diff options
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-1012.patch')
-rw-r--r-- | meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-1012.patch | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-1012.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-1012.patch new file mode 100644 index 000000000..3a8831e60 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2022-1012.patch @@ -0,0 +1,146 @@ +From 1a8ee547da2b64d6a2aedbd38a691578eff14718 Mon Sep 17 00:00:00 2001 +From: Willy Tarreau <w@1wt.eu> +Date: Mon, 2 May 2022 10:46:08 +0200 +Subject: [PATCH] secure_seq: use the 64 bits of the siphash for port offset + calculation + +[ Upstream commit b2d057560b8107c633b39aabe517ff9d93f285e3 ] + +SipHash replaced MD5 in secure_ipv{4,6}_port_ephemeral() via commit +7cd23e5300c1 ("secure_seq: use SipHash in place of MD5"), but the output +remained truncated to 32-bit only. In order to exploit more bits from the +hash, let's make the functions return the full 64-bit of siphash_3u32(). +We also make sure the port offset calculation in __inet_hash_connect() +remains done on 32-bit to avoid the need for div_u64_rem() and an extra +cost on 32-bit systems. + +Cc: Jason A. Donenfeld <Jason@zx2c4.com> +Cc: Moshe Kol <moshe.kol@mail.huji.ac.il> +Cc: Yossi Gilad <yossi.gilad@mail.huji.ac.il> +Cc: Amit Klein <aksecurity@gmail.com> +Reviewed-by: Eric Dumazet <edumazet@google.com> +Signed-off-by: Willy Tarreau <w@1wt.eu> +Signed-off-by: Jakub Kicinski <kuba@kernel.org> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + include/net/inet_hashtables.h | 2 +- + include/net/secure_seq.h | 4 ++-- + net/core/secure_seq.c | 4 ++-- + net/ipv4/inet_hashtables.c | 10 ++++++---- + net/ipv6/inet6_hashtables.c | 4 ++-- + 5 files changed, 13 insertions(+), 11 deletions(-) + +diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h +index f72ec113ae568a..98e1ec1a14f038 100644 +--- a/include/net/inet_hashtables.h ++++ b/include/net/inet_hashtables.h +@@ -425,7 +425,7 @@ static inline void sk_rcv_saddr_set(struct sock *sk, __be32 addr) + } + + int __inet_hash_connect(struct inet_timewait_death_row *death_row, +- struct sock *sk, u32 port_offset, ++ struct sock *sk, u64 port_offset, + int (*check_established)(struct inet_timewait_death_row *, + struct sock *, __u16, + struct inet_timewait_sock **)); +diff --git a/include/net/secure_seq.h b/include/net/secure_seq.h +index d7d2495f83c27c..dac91aa38c5af3 100644 +--- a/include/net/secure_seq.h ++++ b/include/net/secure_seq.h +@@ -4,8 +4,8 @@ + + #include <linux/types.h> + +-u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport); +-u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, ++u64 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport); ++u64 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, + __be16 dport); + u32 secure_tcp_seq(__be32 saddr, __be32 daddr, + __be16 sport, __be16 dport); +diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c +index b5bc680d475536..444cce0184c372 100644 +--- a/net/core/secure_seq.c ++++ b/net/core/secure_seq.c +@@ -94,7 +94,7 @@ u32 secure_tcpv6_seq(const __be32 *saddr, const __be32 *daddr, + } + EXPORT_SYMBOL(secure_tcpv6_seq); + +-u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, ++u64 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, + __be16 dport) + { + const struct { +@@ -142,7 +142,7 @@ u32 secure_tcp_seq(__be32 saddr, __be32 daddr, + } + EXPORT_SYMBOL_GPL(secure_tcp_seq); + +-u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport) ++u64 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport) + { + net_secret_init(); + return siphash_3u32((__force u32)saddr, (__force u32)daddr, +diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c +index 7bd1e10086f0a4..606a4220ebb9d4 100644 +--- a/net/ipv4/inet_hashtables.c ++++ b/net/ipv4/inet_hashtables.c +@@ -504,7 +504,7 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row, + return -EADDRNOTAVAIL; + } + +-static u32 inet_sk_port_offset(const struct sock *sk) ++static u64 inet_sk_port_offset(const struct sock *sk) + { + const struct inet_sock *inet = inet_sk(sk); + +@@ -734,7 +734,7 @@ EXPORT_SYMBOL_GPL(inet_unhash); + static u32 table_perturb[1 << INET_TABLE_PERTURB_SHIFT]; + + int __inet_hash_connect(struct inet_timewait_death_row *death_row, +- struct sock *sk, u32 port_offset, ++ struct sock *sk, u64 port_offset, + int (*check_established)(struct inet_timewait_death_row *, + struct sock *, __u16, struct inet_timewait_sock **)) + { +@@ -777,7 +777,9 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row, + net_get_random_once(table_perturb, sizeof(table_perturb)); + index = hash_32(port_offset, INET_TABLE_PERTURB_SHIFT); + +- offset = (READ_ONCE(table_perturb[index]) + port_offset) % remaining; ++ offset = READ_ONCE(table_perturb[index]) + port_offset; ++ offset %= remaining; ++ + /* In first pass we try ports of @low parity. + * inet_csk_get_port() does the opposite choice. + */ +@@ -859,7 +861,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row, + int inet_hash_connect(struct inet_timewait_death_row *death_row, + struct sock *sk) + { +- u32 port_offset = 0; ++ u64 port_offset = 0; + + if (!inet_sk(sk)->inet_num) + port_offset = inet_sk_port_offset(sk); +diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c +index 0a2e7f22839110..40203255ed88b9 100644 +--- a/net/ipv6/inet6_hashtables.c ++++ b/net/ipv6/inet6_hashtables.c +@@ -308,7 +308,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row, + return -EADDRNOTAVAIL; + } + +-static u32 inet6_sk_port_offset(const struct sock *sk) ++static u64 inet6_sk_port_offset(const struct sock *sk) + { + const struct inet_sock *inet = inet_sk(sk); + +@@ -320,7 +320,7 @@ static u32 inet6_sk_port_offset(const struct sock *sk) + int inet6_hash_connect(struct inet_timewait_death_row *death_row, + struct sock *sk) + { +- u32 port_offset = 0; ++ u64 port_offset = 0; + + if (!inet_sk(sk)->inet_num) + port_offset = inet6_sk_port_offset(sk); |