#23 ChannelSftp.stat not checking for EOF on io.in stream

open
nobody
None
5
2006-04-18
2006-04-18
Anonymous
No

A have a unit test where JSch connects to sshd and then
I kill the
sshd and see what happens to JSch. Most of the time
everything works
fine, but once in a while I get bizzaire errors like
OutOfMemoryError.
I cannot publish the unit test, but I analyzed the
problem and below
is my analysis along with a patch.

Whenever the ssh server closes the connection while the
client is
connected to it, there is a chance that not enough
bytes will be read
(or no bytes at all).

In this code:

public SftpATTRS stat(String path) throws SftpException{
try{
if(path.charAt(0)!='/'){ path=cwd+"/"+path; }

sendSTAT(path.getBytes());
buf.rewind();
int i=io.in.read(buf.buffer, 0, buf.buffer.length);
int length=buf.getInt();
int type=buf.getByte();
if(type!=SSH_FXP_ATTRS){

If io.in.read returns -1; length, type and other fields
will be filled
with whatever was in the buffer before read. This then
causes
OutOfMemory errors down the line when arrays are
allocated with the
sizes read from the uninitialized buffer. My fix was
very simple and
it did help my unit test:

---
old/jsch-0.1.26/src/com/jcraft/jsch/ChannelSftp.java
2006-03-28 06:30:19.000000000 -0800
+++
new/jsch-0.1.26/src/com/jcraft/jsch/ChannelSftp.java
2006-04-11 15:51:32.000000000 -0700
@@ -1441,6 +1441,9 @@
buf.rewind();
int i=io.in.read(buf.buffer, 0, buf.buffer.length);
int length=buf.getInt();
+ if (i == -1) {
+ throw new SftpException(SSH_FX_EOF,
"Unexpected end of file");
+ }
int type=buf.getByte();
if(type!=SSH_FXP_ATTRS){
if(type==SSH_FXP_STATUS){

Admittedly, this fix may not be complete since read()
may have
returned several bytes, but not as many as necessary.

Greg Steuck <greg-jsch@y2006.nest.cx>

Discussion