lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Message-ID: <20191212173156.GA21497@unicorn.suse.cz> Date: Thu, 12 Dec 2019 18:31:56 +0100 From: Michal Kubecek <mkubecek@...e.cz> To: netdev@...r.kernel.org Cc: Eric Dumazet <edumazet@...gle.com>, "David S . Miller" <davem@...emloft.net>, Eric Dumazet <eric.dumazet@...il.com>, Firo Yang <firo.yang@...e.com> Subject: Re: [PATCH net] tcp/dccp: fix possible race __inet_lookup_established() On Wed, Dec 11, 2019 at 09:09:43AM -0800, Eric Dumazet wrote: > Michal Kubecek and Firo Yang did a very nice analysis of crashes > happening in __inet_lookup_established(). > > Since a TCP socket can go from TCP_ESTABLISH to TCP_LISTEN > (via a close()/socket()/listen() cycle) without a RCU grace period, > I should not have changed listeners linkage in their hash table. > > They must use the nulls protocol (Documentation/RCU/rculist_nulls.txt), > so that a lookup can detect a socket in a hash list was moved in > another one. > > Since we added code in commit d296ba60d8e2 ("soreuseport: Resolve > merge conflict for v4/v6 ordering fix"), we have to add > hlist_nulls_add_tail_rcu() helper. > > Fixes: 3b24d854cb35 ("tcp/dccp: do not touch listener sk_refcnt under synflood") > Signed-off-by: Eric Dumazet <edumazet@...gle.com> > Reported-by: Michal Kubecek <mkubecek@...e.cz> > Reported-by: Firo Yang <firo.yang@...e.com> > Link: https://lore.kernel.org/netdev/20191120083919.GH27852@unicorn.suse.cz/ > --- > include/linux/rculist_nulls.h | 37 +++++++++++++++++++++++++++++++++++ > include/net/inet_hashtables.h | 11 +++++++++-- > include/net/sock.h | 5 +++++ > net/ipv4/inet_diag.c | 3 ++- > net/ipv4/inet_hashtables.c | 16 +++++++-------- > net/ipv4/tcp_ipv4.c | 7 ++++--- > 6 files changed, 65 insertions(+), 14 deletions(-) > [...] > diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h > index af2b4c065a042e36135fe6fdcee9833b6b353364..29ef5b7f4005a8e67fd358c136ee6532974efcab 100644 > --- a/include/net/inet_hashtables.h > +++ b/include/net/inet_hashtables.h > @@ -105,11 +105,18 @@ struct inet_bind_hashbucket { > > /* > * Sockets can be hashed in established or listening table > - */ > + * We must use different 'nulls' end-of-chain value for listening > + * hash table, or we might find a socket that was closed and > + * reallocated/inserted into established hash table > + */ Just a nitpick: I don't think this comment is still valid because listening sockets now have RCU protection so that listening socket cannot be freed and reallocated without RCU grace period. (But we still need disjoint ranges to handle the reallocation in the opposite direction.) Other than that, the patch looks good (and better than my work-in-progress patch which I didn't manage to test properly). Reviewed-by: Michal Kubecek <mkubecek@...e.cz> > +#define LISTENING_NULLS_BASE (1U << 29) > struct inet_listen_hashbucket { > spinlock_t lock; > unsigned int count; > - struct hlist_head head; > + union { > + struct hlist_head head; > + struct hlist_nulls_head nulls_head; > + }; > };
Powered by blists - more mailing lists