bugzilla-daemon at mindrot.org
2013-Jul-31 13:12 UTC
[Bug 2135] New: Solaris: race condition in channel forwarding when connect() returns EINPROGRESS
https://bugzilla.mindrot.org/show_bug.cgi?id=2135 Bug ID: 2135 Summary: Solaris: race condition in channel forwarding when connect() returns EINPROGRESS Product: Portable OpenSSH Version: 6.0p1 Hardware: All OS: Solaris Status: NEW Severity: normal Priority: P5 Component: sshd Assignee: unassigned-bugs at mindrot.org Reporter: ivo.raisr at oracle.com Created attachment 2322 --> https://bugzilla.mindrot.org/attachment.cgi?id=2322&action=edit the patch for portable Consider the following scenario with channel forwarding: - sshd runs on the server machine - on the client machine, local port forwarding is setup via the following: ssh -nfN -o GatewayPorts=yes -L 3333:<REMOTE HOST>:5555 -p 2222 <server machine> - <REMOTE HOST> is a faraway machine which takes several tens or hundreds of milliseconds to respond (slow line, geographical distance) - nothing is accepting connections at <REMOTE HOST>:5555 Under normal circumstances, when <REMOTE HOST> is the same machine as <server machine> or is near enough, connect() call in channels.c:connect_next() returns with non-blocking socket which has already finalized connection attempt (errno ECONNREFUSED or ETIMEDOUT, for example). When connection attempt to <REMOTE HOST> takes a while, connect() call returns with errno EINPROGRESS. In this case, outcome of the connection attempt is not yet known. When TCP stack finaly decides then connection attempt has failed, it places the error into pending socket error, where it is later pulled up by select()/poll(). However OpenSSH does a bunch of other stuff between connect() and select(). In particular, it calls channels.c:channel_register_fds. And the Portable OpenSSH (not "pure" OpenSSH) invokes isatty() here. On Solaris, isatty() invokes underlaying ioctl() which gets and clears the pending socket error. Therefore on Solaris, there is a race condition when the following happens: - OpenSSH invokes connect() which returns EINPROGRESS - connection attempt outcome is known after a while and is placed into pending socket error by the TCP stack - OpenSSH invokes isatty() which gets and clears this pending socket error - OpenSSH invokes select() which blocks indefinitely because the pending socket error has been already cleared Had the connection attempt taken a little bit longer and its outcome had been known when OpenSSH was already performing select(), it would behave correctly. However in this case, this particular timing is important. ======================== I realized that isatty() call has been put there into Portable OpenSSH to initialize wfd_isatty attribute of Channel structure. However this attribute is currently used only for AIX. So I would say it is safe to declare and initialize it for AIX only as well. With the attached patch, the problem is fixed. The patch is against OpenSSH 6.0p1 but newer releases are affected as well. -- You are receiving this mail because: You are watching the assignee of the bug.
bugzilla-daemon at mindrot.org
2013-Jul-31 13:46 UTC
[Bug 2135] Solaris: race condition in channel forwarding when connect() returns EINPROGRESS
https://bugzilla.mindrot.org/show_bug.cgi?id=2135 Ivo Raisr <ivo.raisr at oracle.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Priority|P5 |P3 -- You are receiving this mail because: You are watching the assignee of the bug.
bugzilla-daemon at mindrot.org
2013-Aug-01 04:29 UTC
[Bug 2135] Solaris: race condition in channel forwarding when connect() returns EINPROGRESS
https://bugzilla.mindrot.org/show_bug.cgi?id=2135 Damien Miller <djm at mindrot.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |djm at mindrot.org Status|NEW |RESOLVED Resolution|--- |FIXED Blocks| |2076 --- Comment #1 from Damien Miller <djm at mindrot.org> --- This looks like it might have been "fun" to debug. You just made it for openssh-6.3 - thanks. -- You are receiving this mail because: You are watching the assignee of the bug. You are watching someone on the CC list of the bug.
bugzilla-daemon at bugzilla.mindrot.org
2016-Aug-02 00:42 UTC
[Bug 2135] Solaris: race condition in channel forwarding when connect() returns EINPROGRESS
https://bugzilla.mindrot.org/show_bug.cgi?id=2135 Damien Miller <djm at mindrot.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |CLOSED --- Comment #2 from Damien Miller <djm at mindrot.org> --- Close all resolved bugs after 7.3p1 release -- You are receiving this mail because: You are watching someone on the CC list of the bug. You are watching the assignee of the bug.
Maybe Matching Threads
- [Bug 2483] New: use AI_ADDRCONFIG flag for getaddrinfo() hints on Solaris
- Err#150 EINPROGRESS
- [PATCH] Implement remote dynamic TCP forwarding
- Issue with OpenSSH remote forwarding of dynamic ports
- [klibc:master] isatty(): use TCGETS instead of TIOCGPGRP, like dietlibc does