From 34edd9c565b350f55b6d4ca9495a0e3abd8fb367 Mon Sep 17 00:00:00 2001 From: Denis Kirjanov Date: Jan 03 2022 18:43:20 +0000 Subject: ipv6: use prandom_u32() for ID generation (CVE-2021-45485 bsc#1194094). --- diff --git a/patches.suse/ipv6-use-prandom_u32-for-ID-generation.patch b/patches.suse/ipv6-use-prandom_u32-for-ID-generation.patch new file mode 100644 index 0000000..07d770c --- /dev/null +++ b/patches.suse/ipv6-use-prandom_u32-for-ID-generation.patch @@ -0,0 +1,93 @@ +From 62c423d90d1f8d382a266ce98932607b4684fd1e Mon Sep 17 00:00:00 2001 +From: Willy Tarreau +Date: Sat, 29 May 2021 13:07:46 +0200 +Subject: [PATCH] ipv6: use prandom_u32() for ID generation +Patch-mainline: v5.14-rc1 +Git-commit: 62f20e068ccc50d6ab66fdb72ba90da2b9418c99 +References: CVE-2021-45485 bsc#1194094 + +This is a complement to commit aa6dd211e4b1 ("inet: use bigger hash +table for IP ID generation"), but focusing on some specific aspects +of IPv6. + +Contary to IPv4, IPv6 only uses packet IDs with fragments, and with a +minimum MTU of 1280, it's much less easy to force a remote peer to +produce many fragments to explore its ID sequence. In addition packet +IDs are 32-bit in IPv6, which further complicates their analysis. On +the other hand, it is often easier to choose among plenty of possible +source addresses and partially work around the bigger hash table the +commit above permits, which leaves IPv6 partially exposed to some +possibilities of remote analysis at the risk of weakening some +protocols like DNS if some IDs can be predicted with a good enough +probability. + +Given the wide range of permitted IDs, the risk of collision is extremely +low so there's no need to rely on the positive increment algorithm that +is shared with the IPv4 code via ip_idents_reserve(). We have a fast +PRNG, so let's simply call prandom_u32() and be done with it. + +Performance measurements at 10 Gbps couldn't show any difference with +the previous code, even when using a single core, because due to the +large fragments, we're limited to only ~930 kpps at 10 Gbps and the cost +of the random generation is completely offset by other operations and by +the network transfer time. In addition, this change removes the need to +update a shared entry in the idents table so it may even end up being +slightly faster on large scale systems where this matters. + +The risk of at least one collision here is about 1/80 million among +10 IDs, 1/850k among 100 IDs, and still only 1/8.5k among 1000 IDs, +which remains very low compared to IPv4 where all IDs are reused +every 4 to 80ms on a 10 Gbps flow depending on packet sizes. + +Reported-by: Amit Klein +Signed-off-by: Willy Tarreau +Reviewed-by: Eric Dumazet +Link: https://lore.kernel.org/r/20210529110746.6796-1-w@1wt.eu +Signed-off-by: Jakub Kicinski +Signed-off-by: Denis Kirjanov +--- + net/ipv6/output_core.c | 28 +++++----------------------- + 1 file changed, 5 insertions(+), 23 deletions(-) + +diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c +index af36acc1a644..2880dc7d9a49 100644 +--- a/net/ipv6/output_core.c ++++ b/net/ipv6/output_core.c +@@ -15,29 +15,11 @@ static u32 __ipv6_select_ident(struct net *net, + const struct in6_addr *dst, + const struct in6_addr *src) + { +- const struct { +- struct in6_addr dst; +- struct in6_addr src; +- } __aligned(SIPHASH_ALIGNMENT) combined = { +- .dst = *dst, +- .src = *src, +- }; +- 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)); +- +- hash = siphash(&combined, sizeof(combined), &net->ipv4.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 +- * collisions. +- */ +- id = ip_idents_reserve(hash, 1); +- if (unlikely(!id)) +- id = 1 << 31; ++ u32 id; ++ ++ do { ++ id = prandom_u32(); ++ } while (!id); + + return id; + } +-- +2.16.4 + diff --git a/series.conf b/series.conf index 99efadf..fa511f2 100644 --- a/series.conf +++ b/series.conf @@ -51014,6 +51014,7 @@ patches.suse/net-xilinx_emaclite-Do-not-print-real-IOMEM-pointer.patch patches.suse/e100-handle-eeprom-as-little-endian.patch patches.suse/can-hi311x-hi3110_can_probe-silence-clang-warning.patch + patches.suse/ipv6-use-prandom_u32-for-ID-generation.patch patches.suse/mlx5-count-all-link-events.patch patches.suse/ice-Re-organizes-reqstd-avail-R-T-XQ-check-code-for-.patch patches.suse/net-phy-realtek-add-delay-to-fix-RXC-generation-issu.patch