!2 fix CVE-2021-30129

From: @starlet-dx
Reviewed-by: @houyingchao,@myeuler
Signed-off-by: @myeuler
This commit is contained in:
openeuler-ci-bot 2021-08-11 01:36:23 +00:00 committed by Gitee
commit 4ceee46a15
4 changed files with 1696 additions and 1 deletions

1116
CVE-2021-30129-1.patch Normal file

File diff suppressed because it is too large Load Diff

161
CVE-2021-30129-2.patch Normal file
View File

@ -0,0 +1,161 @@
From 5b5bd1dcfa0c2fc250e079e1ebcd643b51f735eb Mon Sep 17 00:00:00 2001
From: Lyor Goldstein <lgoldstein@apache.org>
Date: Fri, 26 Feb 2021 06:54:43 +0200
Subject: [PATCH] [SSHD-1125] Added option to require immediate close of
channel in command ExitCallback invocation
---
.../org/apache/sshd/server/ExitCallback.java | 27 +++++++++++++++++--
.../sshd/server/channel/ChannelSession.java | 10 +++----
.../sshd/util/test/BogusExitCallback.java | 12 ++++++---
.../server/subsystem/sftp/SftpSubsystem.java | 6 +++--
4 files changed, 43 insertions(+), 12 deletions(-)
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/ExitCallback.java b/sshd-core/src/main/java/org/apache/sshd/server/ExitCallback.java
index dfa55be..eb1bca1 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/ExitCallback.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/ExitCallback.java
@@ -30,7 +30,17 @@ public interface ExitCallback {
* @param exitValue the exit value
*/
default void onExit(int exitValue) {
- onExit(exitValue, "");
+ onExit(exitValue, false);
+ }
+
+ /**
+ * Informs the SSH server that the shell has exited
+ *
+ * @param exitValue the exit value
+ * @param closeImmediately whether to also terminate the channel immediately or do a graceful close.
+ */
+ default void onExit(int exitValue, boolean closeImmediately) {
+ onExit(exitValue, "", closeImmediately);
}
/**
@@ -39,5 +49,18 @@ public interface ExitCallback {
* @param exitValue the exit value
* @param exitMessage exit value description
*/
- void onExit(int exitValue, String exitMessage);
+ default void onExit(int exitValue, String exitMessage) {
+ onExit(exitValue, exitMessage, false);
+ }
+
+ /**
+ *
+ * Informs the SSH client/server that the shell has exited
+ *
+ * @param exitValue the exit value
+ * @param exitMessage exit value description
+ * @param closeImmediately whether to also terminate the channel immediately or do a graceful close.
+ */
+ void onExit(int exitValue, String exitMessage, boolean closeImmediately);
+
}
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java b/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
index e54e0e4..484b4f0 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
@@ -684,9 +684,9 @@ public class ChannelSession extends AbstractServerChannel {
tempBuffer = null;
doWriteData(buffer.array(), buffer.rpos(), buffer.available());
}
- command.setExitCallback((exitValue, exitMessage) -> {
+ command.setExitCallback((exitValue, exitMessage, closeImmediately) -> {
try {
- closeShell(exitValue);
+ closeShell(exitValue, closeImmediately);
if (log.isDebugEnabled()) {
log.debug("onExit({}) code={} message='{}' shell closed", ChannelSession.this, exitValue, exitMessage);
}
@@ -798,9 +798,9 @@ public class ChannelSession extends AbstractServerChannel {
return env;
}
- protected void closeShell(int exitValue) throws IOException {
+ protected void closeShell(int exitValue, boolean closeImmediately) throws IOException {
if (log.isDebugEnabled()) {
- log.debug("closeShell({}) exit code={}", this, exitValue);
+ log.debug("closeShell({}) exit code={}, immediate={}", this, exitValue, closeImmediately);
}
if (!isClosing()) {
@@ -810,7 +810,7 @@ public class ChannelSession extends AbstractServerChannel {
sendEof();
sendExitStatus(exitValue);
commandExitFuture.setClosed();
- close(false);
+ close(closeImmediately);
} else {
commandExitFuture.setClosed();
}
diff --git a/sshd-core/src/test/java/org/apache/sshd/util/test/BogusExitCallback.java b/sshd-core/src/test/java/org/apache/sshd/util/test/BogusExitCallback.java
index a4f1ff6..9de602a 100644
--- a/sshd-core/src/test/java/org/apache/sshd/util/test/BogusExitCallback.java
+++ b/sshd-core/src/test/java/org/apache/sshd/util/test/BogusExitCallback.java
@@ -25,21 +25,23 @@ public class BogusExitCallback implements ExitCallback {
private boolean exited;
private int exitValue;
private String exitMessage;
+ private boolean closeImmediately;
public BogusExitCallback() {
super();
}
@Override
- public void onExit(int exitValue) {
- onExit(exitValue, String.valueOf(exitValue));
+ public void onExit(int exitValue, boolean closeImmediately) {
+ onExit(exitValue, String.valueOf(exitValue), closeImmediately);
}
@Override
- public void onExit(int exitValue, String exitMessage) {
+ public void onExit(int exitValue, String exitMessage, boolean closeImmediately) {
this.exited = true;
this.exitValue = exitValue;
this.exitMessage = exitMessage;
+ this.closeImmediately = closeImmediately;
}
public boolean isExited() {
@@ -53,4 +55,8 @@ public class BogusExitCallback implements ExitCallback {
public String getExitMessage() {
return exitMessage;
}
+
+ public boolean isCloseImmediately() {
+ return closeImmediately;
+ }
}
diff --git a/sshd-sftp/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java b/sshd-sftp/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
index 66a0ced..c18b55e 100644
--- a/sshd-sftp/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
+++ b/sshd-sftp/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
@@ -299,6 +299,7 @@ public class SftpSubsystem
@Override
public void run() {
+ int exitCode = 0;
try {
while (true) {
Buffer buffer = requests.take();
@@ -318,10 +319,11 @@ public class SftpSubsystem
if (log.isDebugEnabled()) {
log.debug("run(" + session + ") caught exception details", t);
}
+ exitCode = -1;
}
} finally {
closeAllHandles();
- callback.onExit(0);
+ callback.onExit(exitCode, exitCode != 0);
}
}
--
2.27.0

408
CVE-2021-30129-3.patch Normal file
View File

@ -0,0 +1,408 @@
From f9b2f236e6a663011b50bd7e9a41ec90e6b94831 Mon Sep 17 00:00:00 2001
From: Lyor Goldstein <lgoldstein@apache.org>
Date: Thu, 25 Feb 2021 21:05:49 +0200
Subject: [PATCH] [SSHD-1125] Added mechanism to throttle pending write
requests in BufferedIoOutputStream
---
.../channel/BufferedIoOutputStream.java | 187 ++++++++++++++++--
.../SshChannelBufferedOutputException.java | 41 ++++
.../sshd/core/CoreModuleProperties.java | 19 ++
.../sshd/util/test/AsyncEchoShellFactory.java | 13 +-
.../server/subsystem/sftp/SftpSubsystem.java | 3 +-
5 files changed, 243 insertions(+), 20 deletions(-)
create mode 100644 sshd-core/src/main/java/org/apache/sshd/common/channel/exception/SshChannelBufferedOutputException.java
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/channel/BufferedIoOutputStream.java b/sshd-core/src/main/java/org/apache/sshd/common/channel/BufferedIoOutputStream.java
index 1cb75aa..c95a449 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/channel/BufferedIoOutputStream.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/channel/BufferedIoOutputStream.java
@@ -20,29 +20,55 @@ package org.apache.sshd.common.channel;
import java.io.EOFException;
import java.io.IOException;
+import java.time.Duration;
+import java.util.Objects;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.sshd.common.Closeable;
+import org.apache.sshd.common.PropertyResolver;
+import org.apache.sshd.common.channel.exception.SshChannelBufferedOutputException;
import org.apache.sshd.common.future.SshFutureListener;
import org.apache.sshd.common.io.IoOutputStream;
import org.apache.sshd.common.io.IoWriteFuture;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.buffer.Buffer;
import org.apache.sshd.common.util.closeable.AbstractInnerCloseable;
+import org.apache.sshd.core.CoreModuleProperties;
/**
* An {@link IoOutputStream} capable of queuing write requests
*/
public class BufferedIoOutputStream extends AbstractInnerCloseable implements IoOutputStream {
+ protected final Object id;
+ protected final int channelId;
+ protected final int maxPendingBytesCount;
+ protected final Duration maxWaitForPendingWrites;
protected final IoOutputStream out;
+ protected final AtomicInteger pendingBytesCount = new AtomicInteger();
+ protected final AtomicLong writtenBytesCount = new AtomicLong();
protected final Queue<IoWriteFutureImpl> writes = new ConcurrentLinkedQueue<>();
protected final AtomicReference<IoWriteFutureImpl> currentWrite = new AtomicReference<>();
- protected final Object id;
+ protected final AtomicReference<SshChannelBufferedOutputException> pendingException = new AtomicReference<>();
- public BufferedIoOutputStream(Object id, IoOutputStream out) {
- this.out = out;
- this.id = id;
+ public BufferedIoOutputStream(Object id, int channelId, IoOutputStream out, PropertyResolver resolver) {
+ this(id, channelId, out, CoreModuleProperties.BUFFERED_IO_OUTPUT_MAX_PENDING_WRITE_SIZE.getRequired(resolver),
+ CoreModuleProperties.BUFFERED_IO_OUTPUT_MAX_PENDING_WRITE_WAIT.getRequired(resolver));
+ }
+
+ public BufferedIoOutputStream(
+ Object id, int channelId, IoOutputStream out, int maxPendingBytesCount,
+ Duration maxWaitForPendingWrites) {
+ this.id = Objects.requireNonNull(id, "No stream identifier provided");
+ this.channelId = channelId;
+ this.out = Objects.requireNonNull(out, "No delegate output stream provided");
+ this.maxPendingBytesCount = maxPendingBytesCount;
+ ValidateUtils.checkTrue(maxPendingBytesCount > 0, "Invalid max. pending bytes count: %d", maxPendingBytesCount);
+ this.maxWaitForPendingWrites = Objects.requireNonNull(maxWaitForPendingWrites, "No max. pending time value provided");
}
public Object getId() {
@@ -52,26 +78,114 @@ public class BufferedIoOutputStream extends AbstractInnerCloseable implements Io
@Override
public IoWriteFuture writePacket(Buffer buffer) throws IOException {
if (isClosing()) {
- throw new EOFException("Closed");
+ throw new EOFException("Closed/ing - state=" + state);
}
+ waitForAvailableWriteSpace(buffer.available());
+
IoWriteFutureImpl future = new IoWriteFutureImpl(getId(), buffer);
writes.add(future);
startWriting();
return future;
}
+ protected void waitForAvailableWriteSpace(int requiredSize) throws IOException {
+ /*
+ * NOTE: this code allows a single pending write to give this mechanism "the slip" and
+ * exit the loop "unscathed" even though there is a pending exception. However, the goal
+ * here is to avoid an OOM by having an unlimited accumulation of pending write requests
+ * due to fact that the peer is not consuming the sent data. Please note that the pending
+ * exception is "sticky" - i.e., the next write attempt will fail. This also means that if
+ * the write request that "got away" was the last one by chance and it was consumed by the
+ * peer there will be no exception thrown - which is also fine since as mentioned the goal
+ * is not to enforce a strict limit on the pending bytes size but rather on the accumulation
+ * of the pending write requests.
+ *
+ * We could have counted pending requests rather than bytes. However, we also want to avoid
+ * having a large amount of data pending consumption by the peer as well. This code strikes
+ * such a balance by allowing a single pending request to exceed the limit, but at the same
+ * time prevents too many bytes from pending by having a bunch of pending requests that while
+ * below the imposed number limit may cumulatively represent a lot of pending bytes.
+ */
+
+ long expireTime = System.currentTimeMillis() + maxWaitForPendingWrites.toMillis();
+ synchronized (pendingBytesCount) {
+ for (int count = pendingBytesCount.get();
+ /*
+ * The (count > 0) condition is put in place to allow a single pending
+ * write to exceed the maxPendingBytesCount as long as there are no
+ * other pending ones.
+ */
+ (count > 0)
+ // Not already over the limit or about to be over it
+ && ((count + requiredSize) > maxPendingBytesCount)
+ // No pending exception signaled
+ && (pendingException.get() == null);
+ count = pendingBytesCount.get()) {
+ long remTime = expireTime - System.currentTimeMillis();
+ if (remTime <= 0L) {
+ pendingException.compareAndSet(null,
+ new SshChannelBufferedOutputException(
+ channelId,
+ "Max. pending write timeout expired after " + writtenBytesCount + " bytes"));
+ throw pendingException.get();
+ }
+
+ try {
+ pendingBytesCount.wait(remTime);
+ } catch (InterruptedException e) {
+ pendingException.compareAndSet(null,
+ new SshChannelBufferedOutputException(
+ channelId,
+ "Waiting for pending writes interrupted after " + writtenBytesCount + " bytes"));
+ throw pendingException.get();
+ }
+ }
+
+ IOException e = pendingException.get();
+ if (e != null) {
+ throw e;
+ }
+
+ pendingBytesCount.addAndGet(requiredSize);
+ }
+ }
+
protected void startWriting() throws IOException {
IoWriteFutureImpl future = writes.peek();
+ // No more pending requests
if (future == null) {
return;
}
+ // Don't try to write any further if pending exception signaled
+ Throwable pendingError = pendingException.get();
+ if (pendingError != null) {
+ log.error("startWriting({})[{}] propagate to {} write requests pending error={}[{}]",
+ getId(), out, writes.size(), getClass().getSimpleName(), pendingError.getMessage());
+
+ IoWriteFutureImpl currentFuture = currentWrite.getAndSet(null);
+ for (IoWriteFutureImpl pendingWrite : writes) {
+ // Checking reference by design
+ if (GenericUtils.isSameReference(pendingWrite, currentFuture)) {
+ continue; // will be taken care of when its listener is eventually called
+ }
+
+ future.setValue(pendingError);
+ }
+
+ writes.clear();
+ return;
+ }
+
+ // Cannot honor this request yet since other pending one incomplete
if (!currentWrite.compareAndSet(null, future)) {
return;
}
- out.writePacket(future.getBuffer()).addListener(new SshFutureListener<IoWriteFuture>() {
+ Buffer buffer = future.getBuffer();
+ int bufferSize = buffer.available();
+ out.writePacket(buffer).addListener(new SshFutureListener<IoWriteFuture>() {
@Override
public void operationComplete(IoWriteFuture f) {
if (f.isWritten()) {
@@ -79,32 +193,71 @@ public class BufferedIoOutputStream extends AbstractInnerCloseable implements Io
} else {
future.setValue(f.getException());
}
- finishWrite();
+ finishWrite(future, bufferSize);
+ }
+ });
+ }
+
+ protected void finishWrite(IoWriteFutureImpl future, int bufferSize) {
+ /*
+ * Update the pending bytes count only if successfully written,
+ * otherwise signal an error
+ */
+ if (future.isWritten()) {
+ long writtenSize = writtenBytesCount.addAndGet(bufferSize);
+ int stillPending;
+ synchronized (pendingBytesCount) {
+ stillPending = pendingBytesCount.addAndGet(0 - bufferSize);
+ pendingBytesCount.notifyAll();
}
- @SuppressWarnings("synthetic-access")
- private void finishWrite() {
+ /*
+ * NOTE: since the pending exception is updated outside the synchronized block
+ * a pending write could be successfully enqueued, however this is acceptable
+ * - see comment in waitForAvailableWriteSpace
+ */
+ if (stillPending < 0) {
+ log.error("finishWrite({})[{}] - pending byte counts underflow ({}) after {} bytes", getId(), out, stillPending,
+ writtenSize);
+ pendingException.compareAndSet(null,
+ new SshChannelBufferedOutputException(channelId, "Pending byte counts underflow"));
+ }
+ } else {
+ Throwable t = future.getException();
+ if (t instanceof SshChannelBufferedOutputException) {
+ pendingException.compareAndSet(null, (SshChannelBufferedOutputException) t);
+ } else {
+ pendingException.compareAndSet(null, new SshChannelBufferedOutputException(channelId, t));
+ }
+
+ // In case someone waiting so that they can detect the exception
+ synchronized (pendingBytesCount) {
+ pendingBytesCount.notifyAll();
+ }
+ }
+
writes.remove(future);
currentWrite.compareAndSet(future, null);
try {
startWriting();
} catch (IOException e) {
- log.error("finishWrite({}) failed ({}) re-start writing", out, e.getClass().getSimpleName());
+ if (e instanceof SshChannelBufferedOutputException) {
+ pendingException.compareAndSet(null, (SshChannelBufferedOutputException) e);
+ } else {
+ pendingException.compareAndSet(null, new SshChannelBufferedOutputException(channelId, e));
+ }
+ log.error("finishWrite({})[{}] failed ({}) re-start writing: {}",
+ getId(), out, e.getClass().getSimpleName(), e.getMessage(), e);
}
}
- });
- }
@Override
protected Closeable getInnerCloseable() {
- return builder()
- .when(getId(), writes)
- .close(out)
- .build();
+ return builder().when(getId(), writes).close(out).build();
}
@Override
public String toString() {
- return getClass().getSimpleName() + "[" + out + "]";
+ return getClass().getSimpleName() + "(" + getId() + ")[" + out + "]";
}
}
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/channel/exception/SshChannelBufferedOutputException.java b/sshd-core/src/main/java/org/apache/sshd/common/channel/exception/SshChannelBufferedOutputException.java
new file mode 100644
index 0000000..97e6105
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/channel/exception/SshChannelBufferedOutputException.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sshd.common.channel.exception;
+
+/**
+ * Used by the {@code BufferedIoOutputStream} to signal a non-recoverable error
+ *
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public class SshChannelBufferedOutputException extends SshChannelException {
+ private static final long serialVersionUID = -8663890657820958046L;
+
+ public SshChannelBufferedOutputException(int channelId, String message) {
+ this(channelId, message, null);
+ }
+
+ public SshChannelBufferedOutputException(int channelId, Throwable cause) {
+ this(channelId, cause.getMessage(), cause);
+ }
+
+ public SshChannelBufferedOutputException(int channelId, String message, Throwable cause) {
+ super(channelId, message, cause);
+ }
+}
diff --git a/sshd-core/src/main/java/org/apache/sshd/core/CoreModuleProperties.java b/sshd-core/src/main/java/org/apache/sshd/core/CoreModuleProperties.java
index 9e9b2d2..0d122e5 100644
--- a/sshd-core/src/main/java/org/apache/sshd/core/CoreModuleProperties.java
+++ b/sshd-core/src/main/java/org/apache/sshd/core/CoreModuleProperties.java
@@ -24,6 +24,7 @@ import java.time.Duration;
import org.apache.sshd.client.config.keys.ClientIdentityLoader;
import org.apache.sshd.common.Property;
+import org.apache.sshd.common.SshConstants;
import org.apache.sshd.common.channel.Channel;
import org.apache.sshd.common.session.Session;
import org.apache.sshd.common.util.OsUtils;
@@ -240,6 +241,24 @@ public final class CoreModuleProperties {
public static final Property<Duration> WINDOW_TIMEOUT
= Property.duration("window-timeout", Duration.ZERO);
+ /**
+ * Key used when creating a {@code BufferedIoOutputStream} in order to specify max. allowed unwritten pending bytes.
+ * If this value is exceeded then the code waits up to {@link #BUFFERED_IO_OUTPUT_MAX_PENDING_WRITE_WAIT} for the
+ * pending data to be written and thus make room for the new request.
+ */
+ public static final Property<Integer> BUFFERED_IO_OUTPUT_MAX_PENDING_WRITE_SIZE
+ = Property.integer("buffered-io-output-max-pending-write-size",
+ SshConstants.SSH_REQUIRED_PAYLOAD_PACKET_LENGTH_SUPPORT * 8);
+
+ /**
+ * Key used when creating a {@code BufferedIoOutputStream} in order to specify max. wait time (msec.) for pending
+ * writes to be completed before enqueuing a new request
+ *
+ * @see #BUFFERED_IO_OUTPUT_MAX_PENDING_WRITE_SIZE
+ */
+ public static final Property<Duration> BUFFERED_IO_OUTPUT_MAX_PENDING_WRITE_WAIT
+ = Property.duration("buffered-io-output-max-pending-write-wait", Duration.ofSeconds(30L));
+
/**
* Key used to retrieve the value of the maximum packet size in the configuration properties map.
*/
diff --git a/sshd-core/src/test/java/org/apache/sshd/util/test/AsyncEchoShellFactory.java b/sshd-core/src/test/java/org/apache/sshd/util/test/AsyncEchoShellFactory.java
index de9dbf4..465ff83 100644
--- a/sshd-core/src/test/java/org/apache/sshd/util/test/AsyncEchoShellFactory.java
+++ b/sshd-core/src/test/java/org/apache/sshd/util/test/AsyncEchoShellFactory.java
@@ -99,12 +99,21 @@ public class AsyncEchoShellFactory implements ShellFactory {
@Override
public void setIoOutputStream(IoOutputStream out) {
- this.out = new BufferedIoOutputStream("STDOUT", out);
+ this.out = wrapOutputStream("SHELL-STDOUT", out);
}
@Override
public void setIoErrorStream(IoOutputStream err) {
- this.err = new BufferedIoOutputStream("STDERR", err);
+ this.err = wrapOutputStream("SHELL-STDERR", err);
+ }
+
+ protected BufferedIoOutputStream wrapOutputStream(String prefix, IoOutputStream stream) {
+ if (stream instanceof BufferedIoOutputStream) {
+ return (BufferedIoOutputStream) stream;
+ }
+
+ int channelId = session.getId();
+ return new BufferedIoOutputStream(prefix + "@" + channelId, channelId, stream, session);
}
@Override
diff --git a/sshd-sftp/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java b/sshd-sftp/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
index 66a0ced..15201ec 100644
--- a/sshd-sftp/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
+++ b/sshd-sftp/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
@@ -256,7 +256,8 @@ public class SftpSubsystem
@Override
public void setIoOutputStream(IoOutputStream out) {
- this.out = new BufferedIoOutputStream("sftp out buffer", out);
+ int channelId = channelSession.getId();
+ this.out = new BufferedIoOutputStream("sftp-out@" + channelId, channelId, out, channelSession);
}
@Override
--
2.27.0

View File

@ -1,12 +1,16 @@
Epoch: 1
Name: apache-sshd
Version: 2.2.0
Release: 1
Release: 2
Summary: Apache SSHD
License: ASL 2.0 and ISC
URL: http://mina.apache.org/sshd-project
Source0: https://archive.apache.org/dist/mina/sshd/%{version}/apache-sshd-%{version}-src.tar.gz
Patch0: 0001-Avoid-optional-dependency-on-native-tomcat-APR-libra.patch
Patch1: CVE-2021-30129-1.patch
Patch2: CVE-2021-30129-2.patch
Patch3: CVE-2021-30129-3.patch
BuildRequires: maven-local mvn(junit:junit) mvn(net.i2p.crypto:eddsa) mvn(org.apache.ant:ant)
BuildRequires: mvn(org.apache:apache:pom:) mvn(org.apache.felix:maven-bundle-plugin)
BuildRequires: mvn(org.apache.maven:maven-archiver)
@ -31,6 +35,9 @@ This package provides %{name}.
%prep
%setup -q
%patch0 -p1
%patch1 -p1
%patch2 -p1
%patch3 -p1
rm -rf sshd-core/src/main/java/org/apache/sshd/agent/unix
%pom_remove_dep :spring-framework-bom
%pom_disable_module assembly
@ -64,5 +71,8 @@ rm -rf sshd-core/src/main/java/org/apache/sshd/agent/unix
%license LICENSE.txt NOTICE.txt assembly/src/main/legal/licenses/jbcrypt.txt
%changelog
* Tue Aug 10 2021 yaoxin <yaoxin30@huawei.com> - 2.2.0-2
- Fix CVE-2021-30129
* Thu Aug 6 2020 Jeffery.Gao <gaojianxing@huawei.com> - 2.2.0-1
- Package init