Bug 2476 - ssh fails to report IO errors on stdin/stdout/stderr
Summary: ssh fails to report IO errors on stdin/stdout/stderr
Status: NEW
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: ssh (show other bugs)
Version: 6.0p1
Hardware: Other Linux
: P5 normal
Assignee: Assigned to nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-09-30 02:07 AEST by Ian Jackson
Modified: 2015-10-06 05:09 AEDT (History)
1 user (show)

See Also:


Attachments
report channel write errors (995 bytes, patch)
2015-10-06 05:09 AEDT, Damien Miller
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Ian Jackson 2015-09-30 02:07:45 AEST
Consider, for example:
   ssh localhost date >/dev/full
When ssh attempts to write the output of date (which came via the ssh connection from the server end's invocation of date), it gets ENOSPC.  However, no message is printed to stderr, and the whole invocation exits with status 0.

A similar problem arises with, for example:
  ssh localhost wc -l 0>/dev/null
Here ssh gets EBADF trying to read its own stdin.  However, it signals this to its peer as a normal channel close, and does not report the error at all.

Not reporting these kinds of errors is a problem because it can cause silent data loss.

I think that ssh should instead, when it detects a read or write error on stdin, stdout or stderr: (attempt to) print a message to stderr, and make a note that an error occurred; when the command eventually exits, it should change the exit status of the program to 255 ("an error occurred") according to the manpage.

(In theory it might be possible to extend the channel protocol to allow ssh to signal to sshd that the channel is broken.  However, there is little that sshd could do with this information, since it can't cause errors to be visible at the other ends of the pipes to its child the remote command.)

Thanks for your attention,
Ian.

Transcript demonstrating the problem, and comparing the behaviour with similar commands run locally:

mariner:~> ssh localhost date >/dev/full
mariner:~> echo $?
0
mariner:~> date >/dev/full
date: write error: No space left on device
mariner:~> echo $?
1
mariner:~> ssh localhost wc -l 0>/dev/null 
0
mariner:~> echo $?
0
mariner:~> wc -l 0>/dev/null 
wc: standard input: Bad file descriptor
0
mariner:~> echo $?
1
mariner:~>

(I'm using ssh from Debian wheezy's openssh-client 1:6.0p1-4+deb7u2 on i386.)
Comment 1 Damien Miller 2015-10-06 05:09:32 AEDT
Created attachment 2719 [details]
report channel write errors

It's easy enough to report write errors (see attachment), but I'm not sure the best way to handle them. Clobbering a process' exit status is a bit heavy-handed, since not all processes care about all IO errors.

Some protocol extension that allowed signalling errors back to the client would be nice - it would at least allow the client to report the problem to the user (rather than it being buried in the server's syslog), but it would require both client and server to be running software that supported it.

If there were some way to force a file descriptor error on the client side then we could make this a bit more transparent...