From: Greg Kroah-Hartman Date: Thu, 23 Jun 2022 16:05:57 +0000 (+0200) Subject: 5.10-stable patches X-Git-Tag: v4.9.320~12 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6153479edfd89973dd9f40f09a1e70c186db3021;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: tcp-add-small-random-increments-to-the-source-port.patch tcp-add-some-entropy-in-__inet_hash_connect.patch tcp-drop-the-hash_32-part-from-the-index-calculation.patch tcp-dynamically-allocate-the-perturb-table-used-by-source-ports.patch tcp-increase-source-port-perturb-table-to-2-16.patch tcp-use-different-parts-of-the-port_offset-for-index-and-offset.patch --- diff --git a/queue-5.10/series b/queue-5.10/series index 4c6b59c4453..c7f6b6bf1a5 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -1,3 +1,9 @@ s390-mm-use-non-quiescing-sske-for-kvm-switch-to-keyed-guest.patch zonefs-fix-zonefs_iomap_begin-for-reads.patch usb-gadget-u_ether-fix-regression-in-setting-fixed-mac-address.patch +tcp-add-some-entropy-in-__inet_hash_connect.patch +tcp-use-different-parts-of-the-port_offset-for-index-and-offset.patch +tcp-add-small-random-increments-to-the-source-port.patch +tcp-dynamically-allocate-the-perturb-table-used-by-source-ports.patch +tcp-increase-source-port-perturb-table-to-2-16.patch +tcp-drop-the-hash_32-part-from-the-index-calculation.patch diff --git a/queue-5.10/tcp-add-small-random-increments-to-the-source-port.patch b/queue-5.10/tcp-add-small-random-increments-to-the-source-port.patch new file mode 100644 index 00000000000..2460a7fa3d9 --- /dev/null +++ b/queue-5.10/tcp-add-small-random-increments-to-the-source-port.patch @@ -0,0 +1,53 @@ +From ca7af0402550f9a0b3316d5f1c30904e42ed257d Mon Sep 17 00:00:00 2001 +From: Willy Tarreau +Date: Mon, 2 May 2022 10:46:11 +0200 +Subject: tcp: add small random increments to the source port + +From: Willy Tarreau + +commit ca7af0402550f9a0b3316d5f1c30904e42ed257d upstream. + +Here we're randomly adding between 0 and 7 random increments to the +selected source port in order to add some noise in the source port +selection that will make the next port less predictable. + +With the default port range of 32768-60999 this means a worst case +reuse scenario of 14116/8=1764 connections between two consecutive +uses of the same port, with an average of 14116/4.5=3137. This code +was stressed at more than 800000 connections per second to a fixed +target with all connections closed by the client using RSTs (worst +condition) and only 2 connections failed among 13 billion, despite +the hash being reseeded every 10 seconds, indicating a perfectly +safe situation. + +Cc: Moshe Kol +Cc: Yossi Gilad +Cc: Amit Klein +Reviewed-by: Eric Dumazet +Signed-off-by: Willy Tarreau +Signed-off-by: Jakub Kicinski +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/inet_hashtables.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/net/ipv4/inet_hashtables.c ++++ b/net/ipv4/inet_hashtables.c +@@ -833,11 +833,12 @@ next_port: + return -EADDRNOTAVAIL; + + ok: +- /* If our first attempt found a candidate, skip next candidate +- * in 1/16 of cases to add some noise. ++ /* Here we want to add a little bit of randomness to the next source ++ * port that will be chosen. We use a max() with a random here so that ++ * on low contention the randomness is maximal and on high contention ++ * it may be inexistent. + */ +- if (!i && !(prandom_u32() % 16)) +- i = 2; ++ i = max_t(int, i, (prandom_u32() & 7) * 2); + WRITE_ONCE(table_perturb[index], READ_ONCE(table_perturb[index]) + i + 2); + + /* Head lock still held and bh's disabled */ diff --git a/queue-5.10/tcp-add-some-entropy-in-__inet_hash_connect.patch b/queue-5.10/tcp-add-some-entropy-in-__inet_hash_connect.patch new file mode 100644 index 00000000000..93c5f1d3811 --- /dev/null +++ b/queue-5.10/tcp-add-some-entropy-in-__inet_hash_connect.patch @@ -0,0 +1,49 @@ +From c579bd1b4021c42ae247108f1e6f73dd3f08600c Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Tue, 9 Feb 2021 11:20:28 -0800 +Subject: tcp: add some entropy in __inet_hash_connect() + +From: Eric Dumazet + +commit c579bd1b4021c42ae247108f1e6f73dd3f08600c upstream. + +Even when implementing RFC 6056 3.3.4 (Algorithm 4: Double-Hash +Port Selection Algorithm), a patient attacker could still be able +to collect enough state from an otherwise idle host. + +Idea of this patch is to inject some noise, in the +cases __inet_hash_connect() found a candidate in the first +attempt. + +This noise should not significantly reduce the collision +avoidance, and should be zero if connection table +is already well used. + +Note that this is not implementing RFC 6056 3.3.5 +because we think Algorithm 5 could hurt typical +workloads. + +Signed-off-by: Eric Dumazet +Cc: David Dworken +Cc: Willem de Bruijn +Signed-off-by: David S. Miller +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/inet_hashtables.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/net/ipv4/inet_hashtables.c ++++ b/net/ipv4/inet_hashtables.c +@@ -833,6 +833,11 @@ next_port: + return -EADDRNOTAVAIL; + + ok: ++ /* If our first attempt found a candidate, skip next candidate ++ * in 1/16 of cases to add some noise. ++ */ ++ if (!i && !(prandom_u32() % 16)) ++ i = 2; + WRITE_ONCE(table_perturb[index], READ_ONCE(table_perturb[index]) + i + 2); + + /* Head lock still held and bh's disabled */ diff --git a/queue-5.10/tcp-drop-the-hash_32-part-from-the-index-calculation.patch b/queue-5.10/tcp-drop-the-hash_32-part-from-the-index-calculation.patch new file mode 100644 index 00000000000..719e44278a9 --- /dev/null +++ b/queue-5.10/tcp-drop-the-hash_32-part-from-the-index-calculation.patch @@ -0,0 +1,37 @@ +From e8161345ddbb66e449abde10d2fdce93f867eba9 Mon Sep 17 00:00:00 2001 +From: Willy Tarreau +Date: Mon, 2 May 2022 10:46:14 +0200 +Subject: tcp: drop the hash_32() part from the index calculation + +From: Willy Tarreau + +commit e8161345ddbb66e449abde10d2fdce93f867eba9 upstream. + +In commit 190cc82489f4 ("tcp: change source port randomizarion at +connect() time"), the table_perturb[] array was introduced and an +index was taken from the port_offset via hash_32(). But it turns +out that hash_32() performs a multiplication while the input here +comes from the output of SipHash in secure_seq, that is well +distributed enough to avoid the need for yet another hash. + +Suggested-by: Amit Klein +Reviewed-by: Eric Dumazet +Signed-off-by: Willy Tarreau +Signed-off-by: Jakub Kicinski +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/inet_hashtables.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ipv4/inet_hashtables.c ++++ b/net/ipv4/inet_hashtables.c +@@ -778,7 +778,7 @@ int __inet_hash_connect(struct inet_time + + net_get_random_once(table_perturb, + INET_TABLE_PERTURB_SIZE * sizeof(*table_perturb)); +- index = hash_32(port_offset, INET_TABLE_PERTURB_SHIFT); ++ index = port_offset & (INET_TABLE_PERTURB_SIZE - 1); + + offset = READ_ONCE(table_perturb[index]) + (port_offset >> 32); + offset %= remaining; diff --git a/queue-5.10/tcp-dynamically-allocate-the-perturb-table-used-by-source-ports.patch b/queue-5.10/tcp-dynamically-allocate-the-perturb-table-used-by-source-ports.patch new file mode 100644 index 00000000000..cf6d18973c9 --- /dev/null +++ b/queue-5.10/tcp-dynamically-allocate-the-perturb-table-used-by-source-ports.patch @@ -0,0 +1,61 @@ +From e9261476184be1abd486c9434164b2acbe0ed6c2 Mon Sep 17 00:00:00 2001 +From: Willy Tarreau +Date: Mon, 2 May 2022 10:46:12 +0200 +Subject: tcp: dynamically allocate the perturb table used by source ports + +From: Willy Tarreau + +commit e9261476184be1abd486c9434164b2acbe0ed6c2 upstream. + +We'll need to further increase the size of this table and it's likely +that at some point its size will not be suitable anymore for a static +table. Let's allocate it on boot from inet_hashinfo2_init(), which is +called from tcp_init(). + +Cc: Moshe Kol +Cc: Yossi Gilad +Cc: Amit Klein +Reviewed-by: Eric Dumazet +Signed-off-by: Willy Tarreau +Signed-off-by: Jakub Kicinski +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/inet_hashtables.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +--- a/net/ipv4/inet_hashtables.c ++++ b/net/ipv4/inet_hashtables.c +@@ -731,7 +731,8 @@ EXPORT_SYMBOL_GPL(inet_unhash); + * privacy, this only consumes 1 KB of kernel memory. + */ + #define INET_TABLE_PERTURB_SHIFT 8 +-static u32 table_perturb[1 << INET_TABLE_PERTURB_SHIFT]; ++#define INET_TABLE_PERTURB_SIZE (1 << INET_TABLE_PERTURB_SHIFT) ++static u32 *table_perturb; + + int __inet_hash_connect(struct inet_timewait_death_row *death_row, + struct sock *sk, u64 port_offset, +@@ -774,7 +775,8 @@ int __inet_hash_connect(struct inet_time + if (likely(remaining > 1)) + remaining &= ~1U; + +- net_get_random_once(table_perturb, sizeof(table_perturb)); ++ net_get_random_once(table_perturb, ++ INET_TABLE_PERTURB_SIZE * sizeof(*table_perturb)); + index = hash_32(port_offset, INET_TABLE_PERTURB_SHIFT); + + offset = READ_ONCE(table_perturb[index]) + (port_offset >> 32); +@@ -912,6 +914,12 @@ void __init inet_hashinfo2_init(struct i + low_limit, + high_limit); + init_hashinfo_lhash2(h); ++ ++ /* this one is used for source ports of outgoing connections */ ++ table_perturb = kmalloc_array(INET_TABLE_PERTURB_SIZE, ++ sizeof(*table_perturb), GFP_KERNEL); ++ if (!table_perturb) ++ panic("TCP: failed to alloc table_perturb"); + } + + int inet_hashinfo2_init_mod(struct inet_hashinfo *h) diff --git a/queue-5.10/tcp-increase-source-port-perturb-table-to-2-16.patch b/queue-5.10/tcp-increase-source-port-perturb-table-to-2-16.patch new file mode 100644 index 00000000000..04e23bb0b8a --- /dev/null +++ b/queue-5.10/tcp-increase-source-port-perturb-table-to-2-16.patch @@ -0,0 +1,60 @@ +From 4c2c8f03a5ab7cb04ec64724d7d176d00bcc91e5 Mon Sep 17 00:00:00 2001 +From: Willy Tarreau +Date: Mon, 2 May 2022 10:46:13 +0200 +Subject: tcp: increase source port perturb table to 2^16 + +From: Willy Tarreau + +commit 4c2c8f03a5ab7cb04ec64724d7d176d00bcc91e5 upstream. + +Moshe Kol, Amit Klein, and Yossi Gilad reported being able to accurately +identify a client by forcing it to emit only 40 times more connections +than there are entries in the table_perturb[] table. The previous two +improvements consisting in resalting the secret every 10s and adding +randomness to each port selection only slightly improved the situation, +and the current value of 2^8 was too small as it's not very difficult +to make a client emit 10k connections in less than 10 seconds. + +Thus we're increasing the perturb table from 2^8 to 2^16 so that the +same precision now requires 2.6M connections, which is more difficult in +this time frame and harder to hide as a background activity. The impact +is that the table now uses 256 kB instead of 1 kB, which could mostly +affect devices making frequent outgoing connections. However such +components usually target a small set of destinations (load balancers, +database clients, perf assessment tools), and in practice only a few +entries will be visited, like before. + +A live test at 1 million connections per second showed no performance +difference from the previous value. + +Reported-by: Moshe Kol +Reported-by: Yossi Gilad +Reported-by: Amit Klein +Reviewed-by: Eric Dumazet +Signed-off-by: Willy Tarreau +Signed-off-by: Jakub Kicinski +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/inet_hashtables.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/net/ipv4/inet_hashtables.c ++++ b/net/ipv4/inet_hashtables.c +@@ -726,11 +726,12 @@ EXPORT_SYMBOL_GPL(inet_unhash); + * Note that we use 32bit integers (vs RFC 'short integers') + * because 2^16 is not a multiple of num_ephemeral and this + * property might be used by clever attacker. +- * RFC claims using TABLE_LENGTH=10 buckets gives an improvement, +- * we use 256 instead to really give more isolation and +- * privacy, this only consumes 1 KB of kernel memory. ++ * RFC claims using TABLE_LENGTH=10 buckets gives an improvement, though ++ * attacks were since demonstrated, thus we use 65536 instead to really ++ * give more isolation and privacy, at the expense of 256kB of kernel ++ * memory. + */ +-#define INET_TABLE_PERTURB_SHIFT 8 ++#define INET_TABLE_PERTURB_SHIFT 16 + #define INET_TABLE_PERTURB_SIZE (1 << INET_TABLE_PERTURB_SHIFT) + static u32 *table_perturb; + diff --git a/queue-5.10/tcp-use-different-parts-of-the-port_offset-for-index-and-offset.patch b/queue-5.10/tcp-use-different-parts-of-the-port_offset-for-index-and-offset.patch new file mode 100644 index 00000000000..d27b3251a78 --- /dev/null +++ b/queue-5.10/tcp-use-different-parts-of-the-port_offset-for-index-and-offset.patch @@ -0,0 +1,37 @@ +From 9e9b70ae923baf2b5e8a0ea4fd0c8451801ac526 Mon Sep 17 00:00:00 2001 +From: Willy Tarreau +Date: Mon, 2 May 2022 10:46:09 +0200 +Subject: tcp: use different parts of the port_offset for index and offset + +From: Willy Tarreau + +commit 9e9b70ae923baf2b5e8a0ea4fd0c8451801ac526 upstream. + +Amit Klein suggests that we use different parts of port_offset for the +table's index and the port offset so that there is no direct relation +between them. + +Cc: Jason A. Donenfeld +Cc: Moshe Kol +Cc: Yossi Gilad +Cc: Amit Klein +Reviewed-by: Eric Dumazet +Signed-off-by: Willy Tarreau +Signed-off-by: Jakub Kicinski +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/inet_hashtables.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ipv4/inet_hashtables.c ++++ b/net/ipv4/inet_hashtables.c +@@ -777,7 +777,7 @@ int __inet_hash_connect(struct inet_time + 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; ++ offset = READ_ONCE(table_perturb[index]) + (port_offset >> 32); + offset %= remaining; + + /* In first pass we try ports of @low parity.