* [PATCH net] sctp: call rcu_read_lock before checking for duplicate transport nodes @ 2017-02-28 4:41 Xin Long 2017-02-28 14:23 ` Neil Horman 2017-03-01 17:51 ` David Miller 0 siblings, 2 replies; 5+ messages in thread From: Xin Long @ 2017-02-28 4:41 UTC (permalink / raw) To: network dev, linux-sctp Cc: davem, Marcelo Ricardo Leitner, Neil Horman, Vlad Yasevich, Andrey Konovalov Commit cd2b70875058 ("sctp: check duplicate node before inserting a new transport") called rhltable_lookup() to check for the duplicate transport node in transport rhashtable. But rhltable_lookup() doesn't call rcu_read_lock inside, it could cause a use-after-free issue if it tries to dereference the node that another cpu has freed it. Note that sock lock can not avoid this as it is per sock. This patch is to fix it by calling rcu_read_lock before checking for duplicate transport nodes. Fixes: cd2b70875058 ("sctp: check duplicate node before inserting a new transport") Reported-by: Andrey Konovalov <andreyknvl@google.com> Signed-off-by: Xin Long <lucien.xin@gmail.com> --- net/sctp/input.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/sctp/input.c b/net/sctp/input.c index fc45896..2a28ab2 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -884,14 +884,17 @@ int sctp_hash_transport(struct sctp_transport *t) arg.paddr = &t->ipaddr; arg.lport = htons(t->asoc->base.bind_addr.port); + rcu_read_lock(); list = rhltable_lookup(&sctp_transport_hashtable, &arg, sctp_hash_params); rhl_for_each_entry_rcu(transport, tmp, list, node) if (transport->asoc->ep == t->asoc->ep) { + rcu_read_unlock(); err = -EEXIST; goto out; } + rcu_read_unlock(); err = rhltable_insert_key(&sctp_transport_hashtable, &arg, &t->node, sctp_hash_params); -- 2.1.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH net] sctp: call rcu_read_lock before checking for duplicate transport nodes 2017-02-28 4:41 [PATCH net] sctp: call rcu_read_lock before checking for duplicate transport nodes Xin Long @ 2017-02-28 14:23 ` Neil Horman 2017-02-28 14:37 ` Xin Long 2017-03-01 17:51 ` David Miller 1 sibling, 1 reply; 5+ messages in thread From: Neil Horman @ 2017-02-28 14:23 UTC (permalink / raw) To: Xin Long Cc: network dev, linux-sctp, davem, Marcelo Ricardo Leitner, Vlad Yasevich, Andrey Konovalov On Tue, Feb 28, 2017 at 12:41:29PM +0800, Xin Long wrote: > Commit cd2b70875058 ("sctp: check duplicate node before inserting a > new transport") called rhltable_lookup() to check for the duplicate > transport node in transport rhashtable. > > But rhltable_lookup() doesn't call rcu_read_lock inside, it could cause > a use-after-free issue if it tries to dereference the node that another > cpu has freed it. Note that sock lock can not avoid this as it is per > sock. > > This patch is to fix it by calling rcu_read_lock before checking for > duplicate transport nodes. > > Fixes: cd2b70875058 ("sctp: check duplicate node before inserting a new transport") > Reported-by: Andrey Konovalov <andreyknvl@google.com> > Signed-off-by: Xin Long <lucien.xin@gmail.com> > --- > net/sctp/input.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/net/sctp/input.c b/net/sctp/input.c > index fc45896..2a28ab2 100644 > --- a/net/sctp/input.c > +++ b/net/sctp/input.c > @@ -884,14 +884,17 @@ int sctp_hash_transport(struct sctp_transport *t) > arg.paddr = &t->ipaddr; > arg.lport = htons(t->asoc->base.bind_addr.port); > > + rcu_read_lock(); > list = rhltable_lookup(&sctp_transport_hashtable, &arg, > sctp_hash_params); > > rhl_for_each_entry_rcu(transport, tmp, list, node) > if (transport->asoc->ep == t->asoc->ep) { > + rcu_read_unlock(); > err = -EEXIST; > goto out; > } > + rcu_read_unlock(); > > err = rhltable_insert_key(&sctp_transport_hashtable, &arg, > &t->node, sctp_hash_params); > -- > 2.1.0 > > Hmm, rhltable_insert_key I think returns a pointer to the existing object in the hash table if there is a collision (according to the _rhashtable_insert_fast description). Wouldn't it be better to eliminate the rhl_for_each_entry_rcu entirely, and just check the returned pointer from rhltable_insert_key? Neil ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net] sctp: call rcu_read_lock before checking for duplicate transport nodes 2017-02-28 14:23 ` Neil Horman @ 2017-02-28 14:37 ` Xin Long 2017-02-28 14:58 ` Neil Horman 0 siblings, 1 reply; 5+ messages in thread From: Xin Long @ 2017-02-28 14:37 UTC (permalink / raw) To: Neil Horman Cc: network dev, linux-sctp, davem, Marcelo Ricardo Leitner, Vlad Yasevich, Andrey Konovalov On Tue, Feb 28, 2017 at 10:23 PM, Neil Horman <nhorman@tuxdriver.com> wrote: > On Tue, Feb 28, 2017 at 12:41:29PM +0800, Xin Long wrote: >> Commit cd2b70875058 ("sctp: check duplicate node before inserting a >> new transport") called rhltable_lookup() to check for the duplicate >> transport node in transport rhashtable. >> >> But rhltable_lookup() doesn't call rcu_read_lock inside, it could cause >> a use-after-free issue if it tries to dereference the node that another >> cpu has freed it. Note that sock lock can not avoid this as it is per >> sock. >> >> This patch is to fix it by calling rcu_read_lock before checking for >> duplicate transport nodes. >> >> Fixes: cd2b70875058 ("sctp: check duplicate node before inserting a new transport") >> Reported-by: Andrey Konovalov <andreyknvl@google.com> >> Signed-off-by: Xin Long <lucien.xin@gmail.com> >> --- >> net/sctp/input.c | 3 +++ >> 1 file changed, 3 insertions(+) >> >> diff --git a/net/sctp/input.c b/net/sctp/input.c >> index fc45896..2a28ab2 100644 >> --- a/net/sctp/input.c >> +++ b/net/sctp/input.c >> @@ -884,14 +884,17 @@ int sctp_hash_transport(struct sctp_transport *t) >> arg.paddr = &t->ipaddr; >> arg.lport = htons(t->asoc->base.bind_addr.port); >> >> + rcu_read_lock(); >> list = rhltable_lookup(&sctp_transport_hashtable, &arg, >> sctp_hash_params); >> >> rhl_for_each_entry_rcu(transport, tmp, list, node) >> if (transport->asoc->ep == t->asoc->ep) { >> + rcu_read_unlock(); >> err = -EEXIST; >> goto out; >> } >> + rcu_read_unlock(); >> >> err = rhltable_insert_key(&sctp_transport_hashtable, &arg, >> &t->node, sctp_hash_params); >> -- >> 2.1.0 >> >> > > Hmm, rhltable_insert_key I think returns a pointer to the existing object in the > hash table if there is a collision (according to the _rhashtable_insert_fast > description). Wouldn't it be better to eliminate the rhl_for_each_entry_rcu > entirely, and just check the returned pointer from rhltable_insert_key? I wish it could do it, but rhlist(rhltable_insert_key) allows duplicate node to be inserted, it will never return the existing node. :( I guess the codes you saw are only for the old rhashtable api (they are together with rhlist codes in __rhashtable_insert_fast). Thanks > > Neil > ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net] sctp: call rcu_read_lock before checking for duplicate transport nodes 2017-02-28 14:37 ` Xin Long @ 2017-02-28 14:58 ` Neil Horman 0 siblings, 0 replies; 5+ messages in thread From: Neil Horman @ 2017-02-28 14:58 UTC (permalink / raw) To: Xin Long Cc: network dev, linux-sctp, davem, Marcelo Ricardo Leitner, Vlad Yasevich, Andrey Konovalov On Tue, Feb 28, 2017 at 10:37:35PM +0800, Xin Long wrote: > On Tue, Feb 28, 2017 at 10:23 PM, Neil Horman <nhorman@tuxdriver.com> wrote: > > On Tue, Feb 28, 2017 at 12:41:29PM +0800, Xin Long wrote: > >> Commit cd2b70875058 ("sctp: check duplicate node before inserting a > >> new transport") called rhltable_lookup() to check for the duplicate > >> transport node in transport rhashtable. > >> > >> But rhltable_lookup() doesn't call rcu_read_lock inside, it could cause > >> a use-after-free issue if it tries to dereference the node that another > >> cpu has freed it. Note that sock lock can not avoid this as it is per > >> sock. > >> > >> This patch is to fix it by calling rcu_read_lock before checking for > >> duplicate transport nodes. > >> > >> Fixes: cd2b70875058 ("sctp: check duplicate node before inserting a new transport") > >> Reported-by: Andrey Konovalov <andreyknvl@google.com> > >> Signed-off-by: Xin Long <lucien.xin@gmail.com> > >> --- > >> net/sctp/input.c | 3 +++ > >> 1 file changed, 3 insertions(+) > >> > >> diff --git a/net/sctp/input.c b/net/sctp/input.c > >> index fc45896..2a28ab2 100644 > >> --- a/net/sctp/input.c > >> +++ b/net/sctp/input.c > >> @@ -884,14 +884,17 @@ int sctp_hash_transport(struct sctp_transport *t) > >> arg.paddr = &t->ipaddr; > >> arg.lport = htons(t->asoc->base.bind_addr.port); > >> > >> + rcu_read_lock(); > >> list = rhltable_lookup(&sctp_transport_hashtable, &arg, > >> sctp_hash_params); > >> > >> rhl_for_each_entry_rcu(transport, tmp, list, node) > >> if (transport->asoc->ep == t->asoc->ep) { > >> + rcu_read_unlock(); > >> err = -EEXIST; > >> goto out; > >> } > >> + rcu_read_unlock(); > >> > >> err = rhltable_insert_key(&sctp_transport_hashtable, &arg, > >> &t->node, sctp_hash_params); > >> -- > >> 2.1.0 > >> > >> > > > > Hmm, rhltable_insert_key I think returns a pointer to the existing object in the > > hash table if there is a collision (according to the _rhashtable_insert_fast > > description). Wouldn't it be better to eliminate the rhl_for_each_entry_rcu > > entirely, and just check the returned pointer from rhltable_insert_key? > I wish it could do it, but rhlist(rhltable_insert_key) allows duplicate > node to be inserted, it will never return the existing node. :( > > I guess the codes you saw are only for the old rhashtable api (they are > together with rhlist codes in __rhashtable_insert_fast). > > Thanks > yeah, you're right, can't do it that way Acked-by: Neil Horman <nhorman@tuxdriver.com> > > > > Neil > > > ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net] sctp: call rcu_read_lock before checking for duplicate transport nodes 2017-02-28 4:41 [PATCH net] sctp: call rcu_read_lock before checking for duplicate transport nodes Xin Long 2017-02-28 14:23 ` Neil Horman @ 2017-03-01 17:51 ` David Miller 1 sibling, 0 replies; 5+ messages in thread From: David Miller @ 2017-03-01 17:51 UTC (permalink / raw) To: lucien.xin Cc: netdev, linux-sctp, marcelo.leitner, nhorman, vyasevich, andreyknvl From: Xin Long <lucien.xin@gmail.com> Date: Tue, 28 Feb 2017 12:41:29 +0800 > Commit cd2b70875058 ("sctp: check duplicate node before inserting a > new transport") called rhltable_lookup() to check for the duplicate > transport node in transport rhashtable. > > But rhltable_lookup() doesn't call rcu_read_lock inside, it could cause > a use-after-free issue if it tries to dereference the node that another > cpu has freed it. Note that sock lock can not avoid this as it is per > sock. > > This patch is to fix it by calling rcu_read_lock before checking for > duplicate transport nodes. > > Fixes: cd2b70875058 ("sctp: check duplicate node before inserting a new transport") > Reported-by: Andrey Konovalov <andreyknvl@google.com> > Signed-off-by: Xin Long <lucien.xin@gmail.com> Applied. ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2017-03-01 17:51 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-02-28 4:41 [PATCH net] sctp: call rcu_read_lock before checking for duplicate transport nodes Xin Long 2017-02-28 14:23 ` Neil Horman 2017-02-28 14:37 ` Xin Long 2017-02-28 14:58 ` Neil Horman 2017-03-01 17:51 ` David Miller
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).