Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/main/java/com/jcraft/jsch/Channel.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ public abstract class Channel {
// discarded by the transport layer, killing the connection.
private static final int MAX_LOCAL_PACKET_SIZE = Session.PACKET_MAX_SIZE - 4096;

// cap for the remote maximum packet size announced by the server, see setRemotePacketSize
private static final int MAX_REMOTE_PACKET_SIZE = Session.PACKET_MAX_SIZE - 4096;

int id;
volatile int recipient = -1;
protected byte[] type = Util.str2byte("foo");
Expand Down Expand Up @@ -487,7 +490,10 @@ synchronized void addRemoteWindowSize(long foo) {
}

void setRemotePacketSize(int foo) {
this.rmpsize = foo;
// The remote maximum packet size is attacker-controlled and is used to allocate Buffers.
// It is only an upper bound for what we may send, so capping it is always protocol-compliant.
// Negative values are unsigned values above Integer.MAX_VALUE.
this.rmpsize = (foo < 0 || foo > MAX_REMOTE_PACKET_SIZE) ? MAX_REMOTE_PACKET_SIZE : foo;
}

abstract void run();
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/com/jcraft/jsch/ChannelSftp.java
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,8 @@ public void start() throws JSchException {

PipedOutputStream pos = new PipedOutputStream();
io.setOutputStream(pos);
PipedInputStream pis = new MyPipedInputStream(pos, rq.size() * rmpsize);
PipedInputStream pis = new MyPipedInputStream(pos,
(int) Math.min((long) rq.size() * rmpsize, Integer.MAX_VALUE));
io.setInputStream(pis);

io_in = io.in;
Expand Down
35 changes: 35 additions & 0 deletions src/test/java/com/jcraft/jsch/ChannelRemotePacketSizeTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.jcraft.jsch;

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.Test;

class ChannelRemotePacketSizeTest {

private static final int MAX = Session.PACKET_MAX_SIZE - 4096;

private static int apply(int size) {
Channel c = new ChannelSession();
c.setRemotePacketSize(size);
return c.rmpsize;
}

@Test
void normalValueIsKept() {
assertEquals(32768, apply(32768));
assertEquals(MAX, apply(MAX));
}

@Test
void oversizedValueIsCapped() {
assertEquals(MAX, apply(MAX + 1));
assertEquals(MAX, apply(67108864));
assertEquals(MAX, apply(Integer.MAX_VALUE));
}

@Test
void negativeValueIsCapped() {
assertEquals(MAX, apply(-1));
assertEquals(MAX, apply(Integer.MIN_VALUE));
}
}
Loading