Hello,
I think I found a bug in Jsch-0.1.36 (and all earlier versions):
I have an SSH Server with Sftp version 3, but it does not send
plaintext error messages. Instead, when an SSH_FXP_STATUS
package is received, the "Header" packet indicates only 4
bytes length for the actual status packet; these 4 bytes
hold the (int) error number but no plaintext error message.
I'm not sure if this is allowed by the Sftp protocol standard,
but the fix is not very difficult in Jsch ChannelSftp: whenever
an SSH_FXP_STATUS packet is received, and the length indicated
by the header is only 4 bytes or less, Jsch must not try to
read the plaintext error message.
Because when it tries to do so, it tries reading a "size" of
the plaintext message from uninitialized memory; that "size"
can become a rediculously large number, so Jsch tries to
allocate a ridiculously large byte[] array which leads to
an OutOfMemoryError.
Attached is a "poor man's" version of a patch to fix the
issue. I think that the patch could be improved by
(1) calling a common checkStatus() method rather than
having the same if... code again and again
(2) in getString(), have a safeguard to ensure that
the String being allocated cannot be larger than
the maximum packet size / buffer size.
Please let me know if you consider applying this patch.
I contribute it under the Jsch license.
Thanks,
--
Martin Oberhuber
Wind River Systems, Inc.
Target Management Project Lead, DSDP PMC Member
http://www.eclipse.org/dsdp/tm
Index: com/jcraft/jsch/ChannelSftp.java
===================================================================
RCS file: /export1/data/cvsroot/mober/Jsch/com/jcraft/jsch/ChannelSftp.java,v
retrieving revision 1.1
diff -u -r1.1 ChannelSftp.java
--- com/jcraft/jsch/ChannelSftp.java 6 Nov 2007 13:39:13 -0000 1.1
+++ com/jcraft/jsch/ChannelSftp.java 6 Nov 2007 16:51:21 -0000
@@ -475,7 +475,7 @@
}
if(type==SSH_FXP_STATUS){
int i=buf.getInt();
- throwStatusError(buf, i);
+ throwStatusError(buf, i, length);
}
byte[] handle=buf.getString(); // handle
byte[] data=null;
@@ -621,7 +621,7 @@
}
if(type==SSH_FXP_STATUS){
int i=buf.getInt();
- throwStatusError(buf, i);
+ throwStatusError(buf, i, length);
}
final byte[] handle=buf.getString(); // handle
@@ -884,7 +884,7 @@
if(type==SSH_FXP_STATUS){
int i=buf.getInt();
- throwStatusError(buf, i);
+ throwStatusError(buf, i, length);
}
byte[] handle=buf.getString(); // filename
@@ -913,7 +913,7 @@
if(i==SSH_FX_EOF){
break loop;
}
- throwStatusError(buf, i);
+ throwStatusError(buf, i, length);
}
if(type!=SSH_FXP_DATA){
@@ -1007,7 +1007,7 @@
}
if(type==SSH_FXP_STATUS){
int i=buf.getInt();
- throwStatusError(buf, i);
+ throwStatusError(buf, i, length);
}
final byte[] handle=buf.getString(); // handle
@@ -1225,7 +1225,7 @@
}
if(type==SSH_FXP_STATUS){
int i=buf.getInt();
- throwStatusError(buf, i);
+ throwStatusError(buf, i, length);
}
byte[] handle=buf.getString(); // handle
@@ -1245,7 +1245,7 @@
int i=buf.getInt();
if(i==SSH_FX_EOF)
break;
- throwStatusError(buf, i);
+ throwStatusError(buf, i, length);
}
buf.rewind();
@@ -1379,7 +1379,7 @@
}
int i=buf.getInt();
- throwStatusError(buf, i);
+ throwStatusError(buf, i, length);
}
catch(Exception e){
if(e instanceof SftpException) throw (SftpException)e;
@@ -1422,7 +1422,7 @@
int i=buf.getInt();
if(i==SSH_FX_OK) return;
- throwStatusError(buf, i);
+ throwStatusError(buf, i, length);
}
catch(Exception e){
if(e instanceof SftpException) throw (SftpException)e;
@@ -1474,7 +1474,7 @@
int i=buf.getInt();
if(i==SSH_FX_OK) return;
- throwStatusError(buf, i);
+ throwStatusError(buf, i, length);
}
catch(Exception e){
if(e instanceof SftpException) throw (SftpException)e;
@@ -1507,7 +1507,7 @@
}
int i=buf.getInt();
if(i!=SSH_FX_OK){
- throwStatusError(buf, i);
+ throwStatusError(buf, i, length);
}
}
}
@@ -1661,7 +1661,7 @@
int i=buf.getInt();
if(i!=SSH_FX_OK){
- throwStatusError(buf, i);
+ throwStatusError(buf, i, length);
}
}
}
@@ -1692,7 +1692,7 @@
int i=buf.getInt();
if(i==SSH_FX_OK) return;
- throwStatusError(buf, i);
+ throwStatusError(buf, i, length);
}
catch(Exception e){
if(e instanceof SftpException) throw (SftpException)e;
@@ -1734,7 +1734,7 @@
if(type!=SSH_FXP_ATTRS){
if(type==SSH_FXP_STATUS){
int i=buf.getInt();
- throwStatusError(buf, i);
+ throwStatusError(buf, i, length);
}
throw new SftpException(SSH_FX_FAILURE, "");
}
@@ -1784,7 +1784,7 @@
if(type!=SSH_FXP_ATTRS){
if(type==SSH_FXP_STATUS){
int i=buf.getInt();
- throwStatusError(buf, i);
+ throwStatusError(buf, i, length);
}
throw new SftpException(SSH_FX_FAILURE, "");
}
@@ -1815,7 +1815,7 @@
int i;
if(type==SSH_FXP_STATUS){
i=buf.getInt();
- throwStatusError(buf, i);
+ throwStatusError(buf, i, length);
}
i=buf.getInt(); // count
@@ -1864,7 +1864,7 @@
}
int i=buf.getInt();
if(i!=SSH_FX_OK){
- throwStatusError(buf, i);
+ throwStatusError(buf, i, length);
}
}
catch(Exception e){
@@ -1930,7 +1930,7 @@
}
int i=buf.getInt();
if(i!=SSH_FX_OK){
- throwStatusError(buf, i);
+ throwStatusError(buf, i, length);
}
return true;
}
@@ -2120,7 +2120,7 @@
}
if(type==SSH_FXP_STATUS){
i=buf.getInt();
- throwStatusError(buf, i);
+ throwStatusError(buf, i, length);
}
byte[] handle=buf.getString(); // filename
@@ -2285,6 +2285,13 @@
else{
throw new SftpException(i, "Failure");
}
+ }
+
+ private void throwStatusError(Buffer buf, int i, int length) throws
SftpException{
+ if (server_version<3 || length<=4) {
+ throw new SftpException(i, "Failure");
+ }
+ throwStatusError(buf, i);
}
private static boolean isLocalAbsolutePath(String path){
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
JSch-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jsch-users