From: Rainer Weikusat <rweikusat@mobileactivedefense.com>
To: Jason Baron <jbaron@akamai.com>
Cc: Rainer Weikusat <rweikusat@mobileactivedefense.com>,
Dmitry Vyukov <dvyukov@google.com>,
syzkaller <syzkaller@googlegroups.com>,
Michal Kubecek <mkubecek@suse.cz>,
Al Viro <viro@zeniv.linux.org.uk>,
"linux-fsdevel\@vger.kernel.org" <linux-fsdevel@vger.kernel.org>,
LKML <linux-kernel@vger.kernel.org>,
David Miller <davem@davemloft.net>,
Hannes Frederic Sowa <hannes@stressinduktion.org>,
David Howells <dhowells@redhat.com>,
Paul Moore <paul@paul-moore.com>,
salyzyn@android.com, sds@tycho.nsa.gov, ying.xue@windriver.com,
netdev <netdev@vger.kernel.org>,
Kostya Serebryany <kcc@google.com>,
Alexander Potapenko <glider@google.com>,
Andrey Konovalov <andreyknvl@google.com>,
Sasha Levin <sasha.levin@oracle.com>,
Julien Tinnes <jln@google.com>, Kees Cook <keescook@google.com>,
Mathias Krause <minipli@googlemail.com>
Subject: Re: [PATCH] unix: avoid use-after-free in ep_remove_wait_queue
Date: Tue, 10 Nov 2015 17:38:46 +0000 [thread overview]
Message-ID: <874mgtn49l.fsf@doppelsaurus.mobileactivedefense.com> (raw)
In-Reply-To: <564121D0.2000305@akamai.com> (Jason Baron's message of "Mon, 9 Nov 2015 17:44:32 -0500")
Jason Baron <jbaron@akamai.com> writes:
> On 11/09/2015 09:40 AM, Rainer Weikusat wrote:
[...]
>> - if (unix_peer(other) != sk && unix_recvq_full(other)) {
>> + if (!unix_dgram_peer_recv_ready(sk, other)) {
>> if (!timeo) {
>> - err = -EAGAIN;
>> - goto out_unlock;
>> + if (unix_dgram_peer_wake_me(sk, other)) {
>> + err = -EAGAIN;
>> + goto out_unlock;
>> + }
>> +
>> + goto restart;
>> }
>
>
> So this will cause 'unix_state_lock(other) to be called twice in a
> row if we 'goto restart' (and hence will softlock the box). It just
> needs a 'unix_state_unlock(other);' before the 'goto restart'.
The goto restart was nonsense to begin with in this code path:
Restarting something is necessary after sleeping for some time but for
the case above, execution just continues. I've changed that (updated
patch should follow 'soon') to
if (!unix_dgram_peer_recv_ready(sk, other)) {
if (timeo) {
timeo = unix_wait_for_peer(other, timeo);
err = sock_intr_errno(timeo);
if (signal_pending(current))
goto out_free;
goto restart;
}
if (unix_dgram_peer_wake_me(sk, other)) {
err = -EAGAIN;
goto out_unlock;
}
}
> I also tested this patch with a single unix server and 200 client
> threads doing roughly epoll() followed by write() until -EAGAIN in a
> loop. The throughput for the test was roughly the same as current
> upstream, but the cpu usage was a lot higher. I think its b/c this patch
> takes the server wait queue lock in the _poll() routine. This causes a
> lot of contention. The previous patch you posted for this where you did
> not clear the wait queue on every wakeup and thus didn't need the queue
> lock in poll() (unless we were adding to it), performed much better.
I'm somewhat unsure what to make of that: The previous patch would also
take the wait queue lock whenever poll was about to return 'not
writable' because of the length of the server receive queue unless
another thread using the same client socket also noticed this and
enqueued this same socket already. And "hundreds of clients using a
single client socket in order to send data to a single server socket"
doesn't seem very realistic to me.
Also, this code shouldn't usually be executed as the server should
usually be capable of keeping up with the data sent by clients. If it's
permanently incapable of that, you're effectively performing a
(successful) DDOS against it. Which should result in "high CPU
utilization" in either case. It may be possible to improve this by
tuning/ changing the flow control mechanism. Out of my head, I'd suggest
making the queue longer (the default value is 10) and delaying wake ups
until the server actually did catch up, IOW, the receive queue is empty
or almost empty. But this ought to be done with a different patch.
next prev parent reply other threads:[~2015-11-10 17:38 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-10-12 11:07 Use-after-free in ep_remove_wait_queue Dmitry Vyukov
2015-10-12 12:02 ` Michal Kubecek
2015-10-12 12:14 ` Eric Dumazet
2015-10-12 12:17 ` Dmitry Vyukov
2015-11-06 13:06 ` Dmitry Vyukov
2015-11-06 14:58 ` Jason Baron
2015-11-06 15:15 ` Rainer Weikusat
2015-11-09 14:40 ` [PATCH] unix: avoid use-after-free " Rainer Weikusat
2015-11-09 18:25 ` David Miller
2015-11-10 17:16 ` Rainer Weikusat
2015-11-09 22:44 ` Jason Baron
2015-11-10 17:38 ` Rainer Weikusat [this message]
2015-11-22 21:43 ` alternate queueing mechanism (was: [PATCH] unix: avoid use-after-free in ep_remove_wait_queue) Rainer Weikusat
2015-11-10 21:55 ` [PATCH] unix: avoid use-after-free in ep_remove_wait_queue Rainer Weikusat
2015-11-11 12:28 ` Hannes Frederic Sowa
2015-11-11 16:12 ` Rainer Weikusat
2015-11-11 18:52 ` Hannes Frederic Sowa
2015-11-13 19:06 ` Rainer Weikusat
2015-11-11 17:35 ` Jason Baron
2015-11-12 19:11 ` Rainer Weikusat
2015-11-13 18:51 ` Rainer Weikusat
2015-11-13 22:17 ` Jason Baron
2015-11-15 18:32 ` Rainer Weikusat
2015-11-17 16:08 ` Jason Baron
2015-11-17 18:38 ` Rainer Weikusat
2015-11-16 22:15 ` Rainer Weikusat
2015-11-16 22:28 ` [PATCH] unix: avoid use-after-free in ep_remove_wait_queue (w/ Fixes:) Rainer Weikusat
2015-11-17 16:13 ` Jason Baron
2015-11-17 20:14 ` David Miller
2015-11-17 21:37 ` Rainer Weikusat
2015-11-17 22:09 ` Rainer Weikusat
2015-11-19 23:48 ` Rainer Weikusat
2015-11-17 22:48 ` Rainer Weikusat
2015-11-18 18:15 ` Rainer Weikusat
2015-11-18 23:39 ` more statistics (was: [PATCH] unix: avoid use-after-free in ep_remove_wait_queue (w/ Fixes:)) Rainer Weikusat
2015-11-19 23:52 ` [PATCH] unix: avoid use-after-free in ep_remove_wait_queue (w/ Fixes:) Rainer Weikusat
2015-11-20 16:03 ` Jason Baron
2015-11-20 16:21 ` Rainer Weikusat
2015-11-20 22:07 ` [PATCH] unix: avoid use-after-free in ep_remove_wait_queue Rainer Weikusat
2015-11-23 16:21 ` Jason Baron
2015-11-23 17:30 ` David Miller
2015-11-23 21:37 ` Rainer Weikusat
2015-11-23 23:06 ` Rainer Weikusat
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=874mgtn49l.fsf@doppelsaurus.mobileactivedefense.com \
--to=rweikusat@mobileactivedefense.com \
--cc=andreyknvl@google.com \
--cc=davem@davemloft.net \
--cc=dhowells@redhat.com \
--cc=dvyukov@google.com \
--cc=glider@google.com \
--cc=hannes@stressinduktion.org \
--cc=jbaron@akamai.com \
--cc=jln@google.com \
--cc=kcc@google.com \
--cc=keescook@google.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=minipli@googlemail.com \
--cc=mkubecek@suse.cz \
--cc=netdev@vger.kernel.org \
--cc=paul@paul-moore.com \
--cc=salyzyn@android.com \
--cc=sasha.levin@oracle.com \
--cc=sds@tycho.nsa.gov \
--cc=syzkaller@googlegroups.com \
--cc=viro@zeniv.linux.org.uk \
--cc=ying.xue@windriver.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 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).