From: Greg Kroah-Hartman Date: Tue, 8 Sep 2020 13:21:19 +0000 (+0200) Subject: 4.4-stable patches X-Git-Tag: v4.14.197~17 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=737ad71093774005364bd8c466f4a9610c41b832;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: net-initialize-fastreuse-on-inet_inherit_port.patch net-refactor-bind_bucket-fastreuse-into-helper.patch --- 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 index 00000000000..8d87cf8a6a3 --- /dev/null +++ b/queue-4.4/net-initialize-fastreuse-on-inet_inherit_port.patch @@ -0,0 +1,61 @@ +From d76f3351cea2d927fdf70dd7c06898235035e84e Mon Sep 17 00:00:00 2001 +From: Tim Froidcoeur +Date: Tue, 11 Aug 2020 20:33:24 +0200 +Subject: net: initialize fastreuse on inet_inherit_port + +From: Tim Froidcoeur + +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 +Signed-off-by: Tim Froidcoeur +Signed-off-by: David S. Miller +Signed-off-by: Tim Froidcoeur +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..ac8fa357e2c --- /dev/null +++ b/queue-4.4/net-refactor-bind_bucket-fastreuse-into-helper.patch @@ -0,0 +1,96 @@ +From 62ffc589abb176821662efc4525ee4ac0b9c3894 Mon Sep 17 00:00:00 2001 +From: Tim Froidcoeur +Date: Tue, 11 Aug 2020 20:33:23 +0200 +Subject: net: refactor bind_bucket fastreuse into helper + +From: Tim Froidcoeur + +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 +Signed-off-by: Tim Froidcoeur +Signed-off-by: David S. Miller +Signed-off-by: Tim Froidcoeur +Signed-off-by: Greg Kroah-Hartman +--- + 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); diff --git a/queue-4.4/series b/queue-4.4/series index eb74fee1c0f..c93af0266cf 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -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