From e8458c55da9e68d668055cdeffef36bdf37c1734 Mon Sep 17 00:00:00 2001 From: Marc Strapetz Date: Wed, 20 Jun 2018 16:00:12 +0200 Subject: [PATCH] Fix possible OOME in ChannelInputStream If the buffer is read slower than than incoming data arrives, the buffer might continuing growing endlessly, finally resulting in an OOME. --- .../connection/channel/ChannelInputStream.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/main/java/net/schmizz/sshj/connection/channel/ChannelInputStream.java b/src/main/java/net/schmizz/sshj/connection/channel/ChannelInputStream.java index 5c7f1e64f..950980f98 100644 --- a/src/main/java/net/schmizz/sshj/connection/channel/ChannelInputStream.java +++ b/src/main/java/net/schmizz/sshj/connection/channel/ChannelInputStream.java @@ -126,6 +126,24 @@ public void receive(byte[] data, int offset, int len) buf.putRawBytes(data, offset, len); buf.notifyAll(); } + + // For slow readers, wait until the buffer has been completely read; this ensures that the buffer will be cleared + // in #read and the window position will be reset to 0. Otherwise, if the buffer is read slower than incoming data + // arrives, the buffer might continuing growing endlessly, finally resulting in an OOME. + // Note, that the buffer may still double its size once (provided that the maximum received chunk size is less + // than chan.getLocalMaxPacketSize). + for (; ; ) { + synchronized (buf) { + if (buf.wpos() >= chan.getLocalMaxPacketSize() && buf.available() > 0) { + buf.notifyAll(); + Thread.yield(); + } + else { + break; + } + } + } + // Potential fix for #203 (window consumed below 0). // This seems to be a race condition if we receive more data, while we're already sending a SSH_MSG_CHANNEL_WINDOW_ADJUST // And the window has not expanded yet.