From: Lee Jones <lee.jones@linaro.org>
To: Xin Long <lucien.xin@gmail.com>
Cc: Jakub Kicinski <kuba@kernel.org>,
LKML <linux-kernel@vger.kernel.org>,
Vlad Yasevich <vyasevich@gmail.com>,
Neil Horman <nhorman@tuxdriver.com>,
Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>,
"David S. Miller" <davem@davemloft.net>,
lksctp developers <linux-sctp@vger.kernel.org>,
"H.P. Yarroll" <piggy@acm.org>,
Karl Knutson <karl@athena.chicago.il.us>,
Jon Grimm <jgrimm@us.ibm.com>,
Xingang Guo <xingang.guo@intel.com>,
Hui Huang <hui.huang@nokia.com>,
Sridhar Samudrala <sri@us.ibm.com>,
Daisy Chang <daisyc@us.ibm.com>, Ryan Layer <rmlayer@us.ibm.com>,
Kevin Gao <kevin.gao@intel.com>,
network dev <netdev@vger.kernel.org>
Subject: Re: [RESEND 2/2] sctp: hold cached endpoints to prevent possible UAF
Date: Thu, 16 Dec 2021 16:39:15 +0000 [thread overview]
Message-ID: <Ybtrs56tSBbmyt5c@google.com> (raw)
In-Reply-To: <CADvbK_emZsHVsBvNFk9B5kCZjmAQkMBAx1MtwusDJ-+vt0ukPA@mail.gmail.com>
On Thu, 16 Dec 2021, Xin Long wrote:
> On Wed, Dec 15, 2021 at 8:48 PM Jakub Kicinski <kuba@kernel.org> wrote:
> >
> > On Tue, 14 Dec 2021 21:57:32 +0000 Lee Jones wrote:
> > > The cause of the resultant dump_stack() reported below is a
> > > dereference of a freed pointer to 'struct sctp_endpoint' in
> > > sctp_sock_dump().
> > >
> > > This race condition occurs when a transport is cached into its
> > > associated hash table followed by an endpoint/sock migration to a new
> > > association in sctp_assoc_migrate() prior to their subsequent use in
> > > sctp_diag_dump() which uses sctp_for_each_transport() to walk the hash
> > > table calling into sctp_sock_dump() where the dereference occurs.
> in sctp_sock_dump():
> struct sock *sk = ep->base.sk;
> ... <--[1]
> lock_sock(sk);
>
> Do you mean in [1], the sk is peeled off and gets freed elsewhere?
'ep' and 'sk' are both switched out for new ones in sctp_sock_migrate().
> if that's true, it's still late to do sock_hold(sk) in your this patch.
No, that's not right.
The schedule happens *inside* the lock_sock() call.
So if you take the reference before it, you're good.
> I talked with Marcelo about this before, if the possible UAF in [1] exists,
> the problem also exists in the main RX path sctp_rcv().
>
> > >
> > > BUG: KASAN: use-after-free in sctp_sock_dump+0xa8/0x438 [sctp_diag]
> > > Call trace:
> > > dump_backtrace+0x0/0x2dc
> > > show_stack+0x20/0x2c
> > > dump_stack+0x120/0x144
> > > print_address_description+0x80/0x2f4
> > > __kasan_report+0x174/0x194
> > > kasan_report+0x10/0x18
> > > __asan_load8+0x84/0x8c
> > > sctp_sock_dump+0xa8/0x438 [sctp_diag]
> > > sctp_for_each_transport+0x1e0/0x26c [sctp]
> > > sctp_diag_dump+0x180/0x1f0 [sctp_diag]
> > > inet_diag_dump+0x12c/0x168
> > > netlink_dump+0x24c/0x5b8
> > > __netlink_dump_start+0x274/0x2a8
> > > inet_diag_handler_cmd+0x224/0x274
> > > sock_diag_rcv_msg+0x21c/0x230
> > > netlink_rcv_skb+0xe0/0x1bc
> > > sock_diag_rcv+0x34/0x48
> > > netlink_unicast+0x3b4/0x430
> > > netlink_sendmsg+0x4f0/0x574
> > > sock_write_iter+0x18c/0x1f0
> > > do_iter_readv_writev+0x230/0x2a8
> > > do_iter_write+0xc8/0x2b4
> > > vfs_writev+0xf8/0x184
> > > do_writev+0xb0/0x1a8
> > > __arm64_sys_writev+0x4c/0x5c
> > > el0_svc_common+0x118/0x250
> > > el0_svc_handler+0x3c/0x9c
> > > el0_svc+0x8/0xc
> > >
> > > To prevent this from happening we need to take a references to the
> > > to-be-used/dereferenced 'struct sock' and 'struct sctp_endpoint's
> > > until such a time when we know it can be safely released.
> > >
> > > When KASAN is not enabled, a similar, but slightly different NULL
> > > pointer derefernce crash occurs later along the thread of execution in
> > > inet_sctp_diag_fill() this time.
> Are you able to reproduce this issue?
Yes 100% of the time without this patch.
0% of the time with it applied.
> What I'm thinking is to fix it by freeing sk in call_rcu() by
> sock_set_flag(sock->sk, SOCK_RCU_FREE),
> and add rcu_read_lock() in sctp_sock_dump().
>
> Thanks.
>
> >
> > Are you able to identify where the bug was introduced? Fixes tag would
> > be good to have here.
It's probably been there since the code was introduced.
I'll see how far back we have to go.
> > You should squash the two patches together.
I generally like patches to encapsulate functional changes.
This one depends on the other, but they are not functionally related.
You're the boss though - I'll squash them if you insist.
> > > diff --git a/net/sctp/diag.c b/net/sctp/diag.c
> > > index 760b367644c12..2029b240b6f24 100644
> > > --- a/net/sctp/diag.c
> > > +++ b/net/sctp/diag.c
> > > @@ -301,6 +301,8 @@ static int sctp_sock_dump(struct sctp_transport *tsp, void *p)
> > > struct sctp_association *assoc;
> > > int err = 0;
> > >
> > > + sctp_endpoint_hold(ep);
> > > + sock_hold(sk);
> > > lock_sock(sk);
> > > list_for_each_entry(assoc, &ep->asocs, asocs) {
> > > if (cb->args[4] < cb->args[1])
> > > @@ -341,6 +343,8 @@ static int sctp_sock_dump(struct sctp_transport *tsp, void *p)
> > > cb->args[4] = 0;
> > > release:
> > > release_sock(sk);
> > > + sock_put(sk);
> > > + sctp_endpoint_put(ep);
> > > return err;
> > > }
> > >
> >
--
Lee Jones [李琼斯]
Senior Technical Lead - Developer Services
Linaro.org │ Open source software for Arm SoCs
Follow Linaro: Facebook | Twitter | Blog
next prev parent reply other threads:[~2021-12-16 16:39 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-14 21:57 [RESEND 1/2] sctp: export sctp_endpoint_{hold,put}() for use by seperate modules Lee Jones
2021-12-14 21:57 ` [RESEND 2/2] sctp: hold cached endpoints to prevent possible UAF Lee Jones
2021-12-16 1:48 ` Jakub Kicinski
2021-12-16 16:12 ` Xin Long
2021-12-16 16:39 ` Lee Jones [this message]
2021-12-16 16:52 ` Xin Long
2021-12-16 17:13 ` Lee Jones
2021-12-16 17:14 ` Lee Jones
2021-12-16 18:12 ` Xin Long
2021-12-16 18:22 ` Xin Long
2021-12-16 19:03 ` Lee Jones
2021-12-19 21:20 ` Xin Long
2021-12-20 8:56 ` Lee Jones
2021-12-21 19:52 ` Xin Long
2021-12-22 10:58 ` Lee Jones
2021-12-16 18:25 ` Lee Jones
2021-12-16 20:44 ` Jakub Kicinski
2021-12-17 11:21 ` Lee Jones
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Ybtrs56tSBbmyt5c@google.com \
--to=lee.jones@linaro.org \
--cc=daisyc@us.ibm.com \
--cc=davem@davemloft.net \
--cc=hui.huang@nokia.com \
--cc=jgrimm@us.ibm.com \
--cc=karl@athena.chicago.il.us \
--cc=kevin.gao@intel.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sctp@vger.kernel.org \
--cc=lucien.xin@gmail.com \
--cc=marcelo.leitner@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=nhorman@tuxdriver.com \
--cc=piggy@acm.org \
--cc=rmlayer@us.ibm.com \
--cc=sri@us.ibm.com \
--cc=vyasevich@gmail.com \
--cc=xingang.guo@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.