Bug 773 - OpenSSH silently exits on write failure on stdout/stderr
Summary: OpenSSH silently exits on write failure on stdout/stderr
Status: CLOSED FIXED
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: ssh (show other bugs)
Version: -current
Hardware: All All
: P2 minor
Assignee: Damien Miller
URL:
Keywords: patch
Depends on: 85
Blocks: V_5_1
  Show dependency treegraph
 
Reported: 2003-12-15 18:59 AEDT by Geoff Keating
Modified: 2008-07-22 12:06 AEST (History)
1 user (show)

See Also:


Attachments
Report error on read/write failures (933 bytes, patch)
2007-05-17 18:44 AEST, Damien Miller
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Geoff Keating 2003-12-15 18:59:50 AEDT
If a persistent write error ('disk full') occurs when writing to
stdout of the 'ssh' command, the command can hang and will not produce
an error message.

I can reproduce both problems with OpenSSH 3.7.1p2 on Linux, and the
code affected appears to be common with the current OpenBSD anoncvs
version of OpenSSH.

The write() call that fails is in chan_handle_wfd.  This goes on to
call chan_write_failed, which since the channel is in CHAN_OUTPUT_OPEN
or CHAN_OUTPUT_WAIT_DRAIN (depending on how much output is being sent)
will simply flush the data and then close the file descriptor.
No error message is provided.

[Note that client_process_output does provide an error message in a
similar situation, but it wasn't used since I was using the 2.0
protocol.]

Now, suppose this happens while data is still being sent from a
command running on the SSH server.  When the client gets into
channel_input_data, it will notice that the output channel is no
longer open, and simply return.  This means it won't update
c->local_window.  It also won't call channel_handle_wfd, which would
in any case return directly, which means that c->local_consumed won't
be updated either.  This means that channel_check_window won't ever
send a SSH2_MSG_CHANNEL_WINDOW_ADJUST message, and eventually the
server will stop sending and wait for the client to catch up, which
will never happen.

I could reproduce this easily on Linux by doing

ssh localhost dd if=/dev/zero bs=1024 count=256 > /dev/full

to see the hang, and

ssh localhost dd if=/dev/zero bs=1024 count=1 > /dev/full

to see it terminate with no error message.  If you don't have
/dev/full, just create it as an empty, writable file and then fill up
/dev :-).
Comment 1 Damien Miller 2007-05-17 18:40:42 AEST
I can no longer reproduce the hang with OpenSSH -current, the absence of an error message is still there.
Comment 2 Damien Miller 2007-05-17 18:44:15 AEST
Created attachment 1285 [details]
Report error on read/write failures

This patch may generate unnecessary logspam, so I am going to run with it for a little while before considering it further. Anyone else interested in this bug should do the same.
Comment 3 Damien Miller 2008-05-10 09:53:30 AEST
This should be fixed by closure of bug 85 - the end on which the write fails should now close the corresponding fd of its peer. This make a ssh protocol 2 connection behave much more like a shell redirection. Could you retest?
Comment 4 Damien Miller 2008-06-12 08:16:06 AEST
As mentioned in comment #3, I'm pretty sure that this is fixed. Please reopen this bug if this is not the case.
Comment 5 Damien Miller 2008-07-22 12:06:52 AEST
Mass update RESOLVED->CLOSED after release of openssh-5.1