From: Greg Kroah-Hartman Date: Thu, 2 Jan 2020 21:46:44 +0000 (+0100) Subject: update tcp-dccp-fix-possible-race-__inet_lookup_established.patch for 4.19 4.14 and 4.9 X-Git-Tag: v4.4.208~8 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a0d399217f067ec378d5ada0b86ed203e75f224c;p=thirdparty%2Fkernel%2Fstable-queue.git update tcp-dccp-fix-possible-race-__inet_lookup_established.patch for 4.19 4.14 and 4.9 --- diff --git a/queue-4.14/tcp-dccp-fix-possible-race-__inet_lookup_established.patch b/queue-4.14/tcp-dccp-fix-possible-race-__inet_lookup_established.patch index ede1fef271c..f2559c9e074 100644 --- a/queue-4.14/tcp-dccp-fix-possible-race-__inet_lookup_established.patch +++ b/queue-4.14/tcp-dccp-fix-possible-race-__inet_lookup_established.patch @@ -1,11 +1,11 @@ -From foo@baz Thu 02 Jan 2020 11:13:41 AM CET +From 8dbd76e79a16b45b2ccb01d2f2e08dbf64e71e40 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 13 Dec 2019 18:20:41 -0800 Subject: tcp/dccp: fix possible race __inet_lookup_established() From: Eric Dumazet -[ Upstream commit 8dbd76e79a16b45b2ccb01d2f2e08dbf64e71e40 ] +commit 8dbd76e79a16b45b2ccb01d2f2e08dbf64e71e40 upstream. Michal Kubecek and Firo Yang did a very nice analysis of crashes happening in __inet_lookup_established(). @@ -29,15 +29,18 @@ Reported-by: Firo Yang Reviewed-by: Michal Kubecek Link: https://lore.kernel.org/netdev/20191120083919.GH27852@unicorn.suse.cz/ Signed-off-by: Jakub Kicinski +Signed-off-by: Michal Kubecek Signed-off-by: Greg Kroah-Hartman + --- include/linux/rculist_nulls.h | 37 +++++++++++++++++++++++++++++++++++++ include/net/inet_hashtables.h | 12 +++++++++--- include/net/sock.h | 5 +++++ net/ipv4/inet_diag.c | 3 ++- - net/ipv4/inet_hashtables.c | 15 +++++++-------- + net/ipv4/inet_hashtables.c | 18 +++++++++--------- net/ipv4/tcp_ipv4.c | 7 ++++--- - 6 files changed, 64 insertions(+), 15 deletions(-) + net/ipv6/inet6_hashtables.c | 3 ++- + 7 files changed, 68 insertions(+), 17 deletions(-) --- a/include/linux/rculist_nulls.h +++ b/include/linux/rculist_nulls.h @@ -141,7 +144,19 @@ Signed-off-by: Greg Kroah-Hartman if (!net_eq(sock_net(sk), net)) --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c -@@ -442,10 +442,11 @@ static int inet_reuseport_add_sock(struc +@@ -219,9 +219,10 @@ struct sock *__inet_lookup_listener(stru + int score, hiscore = 0, matches = 0, reuseport = 0; + bool exact_dif = inet_exact_dif_match(net, skb); + struct sock *sk, *result = NULL; ++ struct hlist_nulls_node *node; + u32 phash = 0; + +- sk_for_each_rcu(sk, &ilb->head) { ++ sk_nulls_for_each_rcu(sk, node, &ilb->nulls_head) { + score = compute_score(sk, net, hnum, daddr, + dif, sdif, exact_dif); + if (score > hiscore) { +@@ -442,10 +443,11 @@ static int inet_reuseport_add_sock(struc struct inet_listen_hashbucket *ilb) { struct inet_bind_bucket *tb = inet_csk(sk)->icsk_bind_hash; @@ -154,7 +169,7 @@ Signed-off-by: Greg Kroah-Hartman if (sk2 != sk && sk2->sk_family == sk->sk_family && ipv6_only_sock(sk2) == ipv6_only_sock(sk) && -@@ -480,9 +481,9 @@ int __inet_hash(struct sock *sk, struct +@@ -480,9 +482,9 @@ int __inet_hash(struct sock *sk, struct } if (IS_ENABLED(CONFIG_IPV6) && sk->sk_reuseport && sk->sk_family == AF_INET6) @@ -166,7 +181,7 @@ Signed-off-by: Greg Kroah-Hartman sock_set_flag(sk, SOCK_RCU_FREE); sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); unlock: -@@ -525,10 +526,7 @@ void inet_unhash(struct sock *sk) +@@ -525,10 +527,7 @@ void inet_unhash(struct sock *sk) spin_lock_bh(lock); if (rcu_access_pointer(sk->sk_reuseport_cb)) reuseport_detach_sock(sk); @@ -178,7 +193,7 @@ Signed-off-by: Greg Kroah-Hartman if (done) sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); spin_unlock_bh(lock); -@@ -664,7 +662,8 @@ void inet_hashinfo_init(struct inet_hash +@@ -664,7 +663,8 @@ void inet_hashinfo_init(struct inet_hash for (i = 0; i < INET_LHTABLE_SIZE; i++) { spin_lock_init(&h->listening_hash[i].lock); @@ -218,3 +233,17 @@ Signed-off-by: Greg Kroah-Hartman if (!net_eq(sock_net(sk), net)) continue; if (sk->sk_family == st->family) +--- a/net/ipv6/inet6_hashtables.c ++++ b/net/ipv6/inet6_hashtables.c +@@ -137,9 +137,10 @@ struct sock *inet6_lookup_listener(struc + int score, hiscore = 0, matches = 0, reuseport = 0; + bool exact_dif = inet6_exact_dif_match(net, skb); + struct sock *sk, *result = NULL; ++ struct hlist_nulls_node *node; + u32 phash = 0; + +- sk_for_each(sk, &ilb->head) { ++ sk_nulls_for_each(sk, node, &ilb->nulls_head) { + score = compute_score(sk, net, hnum, daddr, dif, sdif, exact_dif); + if (score > hiscore) { + reuseport = sk->sk_reuseport; diff --git a/queue-4.19/tcp-dccp-fix-possible-race-__inet_lookup_established.patch b/queue-4.19/tcp-dccp-fix-possible-race-__inet_lookup_established.patch index ba7d1bf9c06..1e3c7db7f48 100644 --- a/queue-4.19/tcp-dccp-fix-possible-race-__inet_lookup_established.patch +++ b/queue-4.19/tcp-dccp-fix-possible-race-__inet_lookup_established.patch @@ -1,11 +1,11 @@ -From foo@baz Wed 01 Jan 2020 10:36:29 PM CET +From 8dbd76e79a16b45b2ccb01d2f2e08dbf64e71e40 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 13 Dec 2019 18:20:41 -0800 Subject: tcp/dccp: fix possible race __inet_lookup_established() From: Eric Dumazet -[ Upstream commit 8dbd76e79a16b45b2ccb01d2f2e08dbf64e71e40 ] +commit 8dbd76e79a16b45b2ccb01d2f2e08dbf64e71e40 upstream. Michal Kubecek and Firo Yang did a very nice analysis of crashes happening in __inet_lookup_established(). @@ -29,15 +29,18 @@ Reported-by: Firo Yang Reviewed-by: Michal Kubecek Link: https://lore.kernel.org/netdev/20191120083919.GH27852@unicorn.suse.cz/ Signed-off-by: Jakub Kicinski +Signed-off-by: Michal Kubecek Signed-off-by: Greg Kroah-Hartman + --- include/linux/rculist_nulls.h | 37 +++++++++++++++++++++++++++++++++++++ include/net/inet_hashtables.h | 12 +++++++++--- include/net/sock.h | 5 +++++ net/ipv4/inet_diag.c | 3 ++- - net/ipv4/inet_hashtables.c | 16 ++++++++-------- + net/ipv4/inet_hashtables.c | 19 ++++++++++--------- net/ipv4/tcp_ipv4.c | 7 ++++--- - 6 files changed, 65 insertions(+), 15 deletions(-) + net/ipv6/inet6_hashtables.c | 3 ++- + 7 files changed, 69 insertions(+), 17 deletions(-) --- a/include/linux/rculist_nulls.h +++ b/include/linux/rculist_nulls.h @@ -142,7 +145,24 @@ Signed-off-by: Greg Kroah-Hartman if (!net_eq(sock_net(sk), net)) --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c -@@ -560,10 +560,11 @@ static int inet_reuseport_add_sock(struc +@@ -308,6 +308,7 @@ struct sock *__inet_lookup_listener(stru + bool exact_dif = inet_exact_dif_match(net, skb); + struct inet_listen_hashbucket *ilb2; + struct sock *sk, *result = NULL; ++ struct hlist_nulls_node *node; + int score, hiscore = 0; + unsigned int hash2; + u32 phash = 0; +@@ -343,7 +344,7 @@ struct sock *__inet_lookup_listener(stru + goto done; + + port_lookup: +- sk_for_each_rcu(sk, &ilb->head) { ++ sk_nulls_for_each_rcu(sk, node, &ilb->nulls_head) { + score = compute_score(sk, net, hnum, daddr, + dif, sdif, exact_dif); + if (score > hiscore) { +@@ -560,10 +561,11 @@ static int inet_reuseport_add_sock(struc struct inet_listen_hashbucket *ilb) { struct inet_bind_bucket *tb = inet_csk(sk)->icsk_bind_hash; @@ -155,7 +175,7 @@ Signed-off-by: Greg Kroah-Hartman if (sk2 != sk && sk2->sk_family == sk->sk_family && ipv6_only_sock(sk2) == ipv6_only_sock(sk) && -@@ -599,9 +600,9 @@ int __inet_hash(struct sock *sk, struct +@@ -599,9 +601,9 @@ int __inet_hash(struct sock *sk, struct } if (IS_ENABLED(CONFIG_IPV6) && sk->sk_reuseport && sk->sk_family == AF_INET6) @@ -167,7 +187,7 @@ Signed-off-by: Greg Kroah-Hartman inet_hash2(hashinfo, sk); ilb->count++; sock_set_flag(sk, SOCK_RCU_FREE); -@@ -650,11 +651,9 @@ void inet_unhash(struct sock *sk) +@@ -650,11 +652,9 @@ void inet_unhash(struct sock *sk) reuseport_detach_sock(sk); if (ilb) { inet_unhash2(hashinfo, sk); @@ -181,7 +201,7 @@ Signed-off-by: Greg Kroah-Hartman sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); unlock: spin_unlock_bh(lock); -@@ -790,7 +789,8 @@ void inet_hashinfo_init(struct inet_hash +@@ -790,7 +790,8 @@ void inet_hashinfo_init(struct inet_hash for (i = 0; i < INET_LHTABLE_SIZE; i++) { spin_lock_init(&h->listening_hash[i].lock); @@ -221,3 +241,22 @@ Signed-off-by: Greg Kroah-Hartman if (!net_eq(sock_net(sk), net)) continue; if (sk->sk_family == afinfo->family) +--- a/net/ipv6/inet6_hashtables.c ++++ b/net/ipv6/inet6_hashtables.c +@@ -171,6 +171,7 @@ struct sock *inet6_lookup_listener(struc + bool exact_dif = inet6_exact_dif_match(net, skb); + struct inet_listen_hashbucket *ilb2; + struct sock *sk, *result = NULL; ++ struct hlist_nulls_node *node; + int score, hiscore = 0; + unsigned int hash2; + u32 phash = 0; +@@ -206,7 +207,7 @@ struct sock *inet6_lookup_listener(struc + goto done; + + port_lookup: +- sk_for_each(sk, &ilb->head) { ++ sk_nulls_for_each(sk, node, &ilb->nulls_head) { + score = compute_score(sk, net, hnum, daddr, dif, sdif, exact_dif); + if (score > hiscore) { + if (sk->sk_reuseport) { diff --git a/queue-4.9/tcp-dccp-fix-possible-race-__inet_lookup_established.patch b/queue-4.9/tcp-dccp-fix-possible-race-__inet_lookup_established.patch index e7e250d525f..1da4675b68e 100644 --- a/queue-4.9/tcp-dccp-fix-possible-race-__inet_lookup_established.patch +++ b/queue-4.9/tcp-dccp-fix-possible-race-__inet_lookup_established.patch @@ -1,11 +1,11 @@ -From foo@baz Thu 02 Jan 2020 11:13:41 AM CET +From 8dbd76e79a16b45b2ccb01d2f2e08dbf64e71e40 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 13 Dec 2019 18:20:41 -0800 Subject: tcp/dccp: fix possible race __inet_lookup_established() From: Eric Dumazet -[ Upstream commit 8dbd76e79a16b45b2ccb01d2f2e08dbf64e71e40 ] +commit 8dbd76e79a16b45b2ccb01d2f2e08dbf64e71e40 upstream. Michal Kubecek and Firo Yang did a very nice analysis of crashes happening in __inet_lookup_established(). @@ -29,15 +29,18 @@ Reported-by: Firo Yang Reviewed-by: Michal Kubecek Link: https://lore.kernel.org/netdev/20191120083919.GH27852@unicorn.suse.cz/ Signed-off-by: Jakub Kicinski +Signed-off-by: Michal Kubecek Signed-off-by: Greg Kroah-Hartman + --- include/linux/rculist_nulls.h | 37 +++++++++++++++++++++++++++++++++++++ include/net/inet_hashtables.h | 12 +++++++++--- include/net/sock.h | 5 +++++ net/ipv4/inet_diag.c | 3 ++- - net/ipv4/inet_hashtables.c | 15 +++++++-------- + net/ipv4/inet_hashtables.c | 18 +++++++++--------- net/ipv4/tcp_ipv4.c | 7 ++++--- - 6 files changed, 64 insertions(+), 15 deletions(-) + net/ipv6/inet6_hashtables.c | 3 ++- + 7 files changed, 68 insertions(+), 17 deletions(-) --- a/include/linux/rculist_nulls.h +++ b/include/linux/rculist_nulls.h @@ -142,7 +145,19 @@ Signed-off-by: Greg Kroah-Hartman if (!net_eq(sock_net(sk), net)) --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c -@@ -441,10 +441,11 @@ static int inet_reuseport_add_sock(struc +@@ -218,9 +218,10 @@ struct sock *__inet_lookup_listener(stru + int score, hiscore = 0, matches = 0, reuseport = 0; + bool exact_dif = inet_exact_dif_match(net, skb); + struct sock *sk, *result = NULL; ++ struct hlist_nulls_node *node; + u32 phash = 0; + +- sk_for_each_rcu(sk, &ilb->head) { ++ sk_nulls_for_each_rcu(sk, node, &ilb->nulls_head) { + score = compute_score(sk, net, hnum, daddr, dif, exact_dif); + if (score > hiscore) { + reuseport = sk->sk_reuseport; +@@ -441,10 +442,11 @@ static int inet_reuseport_add_sock(struc bool match_wildcard)) { struct inet_bind_bucket *tb = inet_csk(sk)->icsk_bind_hash; @@ -155,7 +170,7 @@ Signed-off-by: Greg Kroah-Hartman if (sk2 != sk && sk2->sk_family == sk->sk_family && ipv6_only_sock(sk2) == ipv6_only_sock(sk) && -@@ -482,9 +483,9 @@ int __inet_hash(struct sock *sk, struct +@@ -482,9 +484,9 @@ int __inet_hash(struct sock *sk, struct } if (IS_ENABLED(CONFIG_IPV6) && sk->sk_reuseport && sk->sk_family == AF_INET6) @@ -167,7 +182,7 @@ Signed-off-by: Greg Kroah-Hartman sock_set_flag(sk, SOCK_RCU_FREE); sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); unlock: -@@ -527,10 +528,7 @@ void inet_unhash(struct sock *sk) +@@ -527,10 +529,7 @@ void inet_unhash(struct sock *sk) spin_lock_bh(lock); if (rcu_access_pointer(sk->sk_reuseport_cb)) reuseport_detach_sock(sk); @@ -179,7 +194,7 @@ Signed-off-by: Greg Kroah-Hartman if (done) sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); spin_unlock_bh(lock); -@@ -666,7 +664,8 @@ void inet_hashinfo_init(struct inet_hash +@@ -666,7 +665,8 @@ void inet_hashinfo_init(struct inet_hash for (i = 0; i < INET_LHTABLE_SIZE; i++) { spin_lock_init(&h->listening_hash[i].lock); @@ -219,3 +234,17 @@ Signed-off-by: Greg Kroah-Hartman if (!net_eq(sock_net(sk), net)) continue; if (sk->sk_family == st->family) +--- a/net/ipv6/inet6_hashtables.c ++++ b/net/ipv6/inet6_hashtables.c +@@ -133,9 +133,10 @@ struct sock *inet6_lookup_listener(struc + int score, hiscore = 0, matches = 0, reuseport = 0; + bool exact_dif = inet6_exact_dif_match(net, skb); + struct sock *sk, *result = NULL; ++ struct hlist_nulls_node *node; + u32 phash = 0; + +- sk_for_each(sk, &ilb->head) { ++ sk_nulls_for_each(sk, node, &ilb->nulls_head) { + score = compute_score(sk, net, hnum, daddr, dif, exact_dif); + if (score > hiscore) { + reuseport = sk->sk_reuseport;