]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 8 Sep 2020 13:21:19 +0000 (15:21 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 8 Sep 2020 13:21:19 +0000 (15:21 +0200)
added patches:
net-initialize-fastreuse-on-inet_inherit_port.patch
net-refactor-bind_bucket-fastreuse-into-helper.patch

queue-4.4/net-initialize-fastreuse-on-inet_inherit_port.patch [new file with mode: 0644]
queue-4.4/net-refactor-bind_bucket-fastreuse-into-helper.patch [new file with mode: 0644]
queue-4.4/series

diff --git a/queue-4.4/net-initialize-fastreuse-on-inet_inherit_port.patch b/queue-4.4/net-initialize-fastreuse-on-inet_inherit_port.patch
new file mode 100644 (file)
index 0000000..8d87cf8
--- /dev/null
@@ -0,0 +1,61 @@
+From d76f3351cea2d927fdf70dd7c06898235035e84e Mon Sep 17 00:00:00 2001
+From: Tim Froidcoeur <tim.froidcoeur@tessares.net>
+Date: Tue, 11 Aug 2020 20:33:24 +0200
+Subject: net: initialize fastreuse on inet_inherit_port
+
+From: Tim Froidcoeur <tim.froidcoeur@tessares.net>
+
+commit d76f3351cea2d927fdf70dd7c06898235035e84e upstream.
+
+In the case of TPROXY, bind_conflict optimizations for SO_REUSEADDR or
+SO_REUSEPORT are broken, possibly resulting in O(n) instead of O(1) bind
+behaviour or in the incorrect reuse of a bind.
+
+the kernel keeps track for each bind_bucket if all sockets in the
+bind_bucket support SO_REUSEADDR or SO_REUSEPORT in two fastreuse flags.
+These flags allow skipping the costly bind_conflict check when possible
+(meaning when all sockets have the proper SO_REUSE option).
+
+For every socket added to a bind_bucket, these flags need to be updated.
+As soon as a socket that does not support reuse is added, the flag is
+set to false and will never go back to true, unless the bind_bucket is
+deleted.
+
+Note that there is no mechanism to re-evaluate these flags when a socket
+is removed (this might make sense when removing a socket that would not
+allow reuse; this leaves room for a future patch).
+
+For this optimization to work, it is mandatory that these flags are
+properly initialized and updated.
+
+When a child socket is created from a listen socket in
+__inet_inherit_port, the TPROXY case could create a new bind bucket
+without properly initializing these flags, thus preventing the
+optimization to work. Alternatively, a socket not allowing reuse could
+be added to an existing bind bucket without updating the flags, causing
+bind_conflict to never be called as it should.
+
+Call inet_csk_update_fastreuse when __inet_inherit_port decides to create
+a new bind_bucket or use a different bind_bucket than the one of the
+listen socket.
+
+Fixes: 093d282321da ("tproxy: fix hash locking issue when using port redirection in __inet_inherit_port()")
+Acked-by: Matthieu Baerts <matthieu.baerts@tessares.net>
+Signed-off-by: Tim Froidcoeur <tim.froidcoeur@tessares.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Tim Froidcoeur <tim.froidcoeur@tessares.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/inet_hashtables.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/ipv4/inet_hashtables.c
++++ b/net/ipv4/inet_hashtables.c
+@@ -160,6 +160,7 @@ int __inet_inherit_port(const struct soc
+                               return -ENOMEM;
+                       }
+               }
++              inet_csk_update_fastreuse(tb, child);
+       }
+       inet_bind_hash(child, tb, port);
+       spin_unlock(&head->lock);
diff --git a/queue-4.4/net-refactor-bind_bucket-fastreuse-into-helper.patch b/queue-4.4/net-refactor-bind_bucket-fastreuse-into-helper.patch
new file mode 100644 (file)
index 0000000..ac8fa35
--- /dev/null
@@ -0,0 +1,96 @@
+From 62ffc589abb176821662efc4525ee4ac0b9c3894 Mon Sep 17 00:00:00 2001
+From: Tim Froidcoeur <tim.froidcoeur@tessares.net>
+Date: Tue, 11 Aug 2020 20:33:23 +0200
+Subject: net: refactor bind_bucket fastreuse into helper
+
+From: Tim Froidcoeur <tim.froidcoeur@tessares.net>
+
+commit 62ffc589abb176821662efc4525ee4ac0b9c3894 upstream.
+
+Refactor the fastreuse update code in inet_csk_get_port into a small
+helper function that can be called from other places.
+
+Acked-by: Matthieu Baerts <matthieu.baerts@tessares.net>
+Signed-off-by: Tim Froidcoeur <tim.froidcoeur@tessares.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Tim Froidcoeur <tim.froidcoeur@tessares.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/inet_connection_sock.h |    4 +++
+ net/ipv4/inet_connection_sock.c    |   46 ++++++++++++++++++++++---------------
+ 2 files changed, 32 insertions(+), 18 deletions(-)
+
+--- a/include/net/inet_connection_sock.h
++++ b/include/net/inet_connection_sock.h
+@@ -319,5 +319,9 @@ int inet_csk_compat_getsockopt(struct so
+ int inet_csk_compat_setsockopt(struct sock *sk, int level, int optname,
+                              char __user *optval, unsigned int optlen);
++/* update the fast reuse flag when adding a socket */
++void inet_csk_update_fastreuse(struct inet_bind_bucket *tb,
++                             struct sock *sk);
++
+ struct dst_entry *inet_csk_update_pmtu(struct sock *sk, u32 mtu);
+ #endif /* _INET_CONNECTION_SOCK_H */
+--- a/net/ipv4/inet_connection_sock.c
++++ b/net/ipv4/inet_connection_sock.c
+@@ -87,6 +87,31 @@ int inet_csk_bind_conflict(const struct
+ }
+ EXPORT_SYMBOL_GPL(inet_csk_bind_conflict);
++void inet_csk_update_fastreuse(struct inet_bind_bucket *tb,
++                             struct sock *sk)
++{
++      kuid_t uid = sock_i_uid(sk);
++
++      if (hlist_empty(&tb->owners)) {
++              if (sk->sk_reuse && sk->sk_state != TCP_LISTEN)
++                      tb->fastreuse = 1;
++              else
++                      tb->fastreuse = 0;
++              if (sk->sk_reuseport) {
++                      tb->fastreuseport = 1;
++                      tb->fastuid = uid;
++              } else
++                      tb->fastreuseport = 0;
++      } else {
++              if (tb->fastreuse &&
++                  (!sk->sk_reuse || sk->sk_state == TCP_LISTEN))
++                      tb->fastreuse = 0;
++              if (tb->fastreuseport &&
++                  (!sk->sk_reuseport || !uid_eq(tb->fastuid, uid)))
++                      tb->fastreuseport = 0;
++      }
++}
++
+ /* Obtain a reference to a local port for the given sock,
+  * if snum is zero it means select any available local port.
+  */
+@@ -216,24 +241,9 @@ tb_not_found:
+       if (!tb && (tb = inet_bind_bucket_create(hashinfo->bind_bucket_cachep,
+                                       net, head, snum)) == NULL)
+               goto fail_unlock;
+-      if (hlist_empty(&tb->owners)) {
+-              if (sk->sk_reuse && sk->sk_state != TCP_LISTEN)
+-                      tb->fastreuse = 1;
+-              else
+-                      tb->fastreuse = 0;
+-              if (sk->sk_reuseport) {
+-                      tb->fastreuseport = 1;
+-                      tb->fastuid = uid;
+-              } else
+-                      tb->fastreuseport = 0;
+-      } else {
+-              if (tb->fastreuse &&
+-                  (!sk->sk_reuse || sk->sk_state == TCP_LISTEN))
+-                      tb->fastreuse = 0;
+-              if (tb->fastreuseport &&
+-                  (!sk->sk_reuseport || !uid_eq(tb->fastuid, uid)))
+-                      tb->fastreuseport = 0;
+-      }
++
++      inet_csk_update_fastreuse(tb, sk);
++
+ success:
+       if (!inet_csk(sk)->icsk_bind_hash)
+               inet_bind_hash(sk, tb, snum);
index eb74fee1c0ffd04643d33bfde8b38bc2b612452a..c93af0266cfccc4a565c051cb660a86b712e4436 100644 (file)
@@ -42,3 +42,5 @@ alsa-ca0106-fix-error-code-handling.patch
 alsa-pcm-oss-remove-superfluous-warn_on-for-mulaw-sanity-check.patch
 dm-cache-metadata-avoid-returning-cmd-bm-wild-pointer-on-error.patch
 dm-thin-metadata-avoid-returning-cmd-bm-wild-pointer-on-error.patch
+net-refactor-bind_bucket-fastreuse-into-helper.patch
+net-initialize-fastreuse-on-inet_inherit_port.patch