From: Al Viro <viro@zeniv.linux.org.uk>
To: Rainer Weikusat <rweikusat@mobileactivedefense.com>,
Jason Baron <jbaron@akamai.com>
Cc: netdev@vger.kernel.org
Subject: Re: [RFC] nasty corner case in unix_dgram_sendmsg()
Date: Tue, 26 Feb 2019 06:28:17 +0000 [thread overview]
Message-ID: <20190226062817.GA17962@ZenIV.linux.org.uk> (raw)
In-Reply-To: <20190225035121.GH2217@ZenIV.linux.org.uk>
On Mon, Feb 25, 2019 at 03:51:21AM +0000, Al Viro wrote:
> PS: unix_dgram_sendmsg() is really much too subtle for its own good -
> AFAICS, it *does* avoid blocking operations under sk->lock, but proof
> is considerably more complex than one would like it to be...
Several questions about the whole peer_wake mechanism:
1) why do we even bother with that for SOCK_SEQPACKET? AFAICS, there
we do *not* hit unix_wait_for_peer() on send - it's conditional upon
if (other != sk &&
unlikely(unix_peer(other) != sk && unix_recvq_full(other))) {
after we'd checked that other is non-NULL and not dead. For seqpacket
we start with both ends of connection having unix_peer() pointing to
each other and only changed to NULL when one of the ends gets closed.
The socket we'd passed to sendmsg is obviously not dead yet, and we'd
verified that other isn't dead either. So unix_peer(other) must be
equal to sk and we don't go into that if.
In unix_dgram_poll() we might get to unix_dgram_peer_wake_me() for
seqpacket, but only in case when other is dead. In that case
unix_dgram_peer_wake_me() will insert our peer_wake into queue,
see SOCK_DEAD, remove peer_wake from queue and return false.
AFAICS, that serves no purpose whatsoever...
2) the logics in sendmsg is very odd:
* if we'd detected n:1 send *and* found that we need to
wait, do so (not using the peer_wake - other's peer_wait is not
going away). No questions there.
* if we'd detected n:1 send *and* found that we need to
wait, but don't have any remaining timeout, we lock both ends
and check if unix_peer(sk) is (now) not equal to other, either
because it never had or because we'd been hit by connect(2) while
we'd been doing the locking. In that case we fail with -EAGAIN.
Fair enough, but
* if after relocking we see that unix_peer(sk) now
is equal to other, we arrange for wakeup forwarding from other's
peer_wait *and* if that has (likely) succeeded we fail with -EAGAIN.
Huh? What's the point? The only thing that depends upon that
wakeup forwarding is poll, and _that_ will set the forwarding up
on its own.
* if we'd failed (either because other is dead now or
because its queue is not full), we go back to restart_locked.
If it's dead, we'll sod off with ECONNREFUSED, if it's not
full anymore, we'll send the damn thing.
All of that comes at the cost of considerable headache in
unix_dgram_sendmsg() - flag-conditional locking, etc. Why do
we bother? What's wrong with simple "n:1 case detected, queue
full, no timeout left, return -EAGAIN and be done with that"?
IDGI... Am I missing something subtle going on here?
I understand what peer_wake is for, and the poll side of things
is fine; it's sendmsg one that looks weird. What's going on
there?
next prev parent reply other threads:[~2019-02-26 6:28 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-02-25 3:51 [RFC] nasty corner case in unix_dgram_sendmsg() Al Viro
2019-02-26 6:28 ` Al Viro [this message]
2019-02-26 6:38 ` Al Viro
2019-02-26 15:31 ` Rainer Weikusat
2019-02-26 19:03 ` Al Viro
2019-02-26 20:35 ` Jason Baron
2019-02-26 23:59 ` Al Viro
2019-02-27 16:45 ` Jason Baron
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=20190226062817.GA17962@ZenIV.linux.org.uk \
--to=viro@zeniv.linux.org.uk \
--cc=jbaron@akamai.com \
--cc=netdev@vger.kernel.org \
--cc=rweikusat@mobileactivedefense.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).