[Git][java-team/netty][bullseye] 3 commits: Fix CVE-2023-34462 and CVE-2023-44487.

Markus Koschany (@apo) gitlab at salsa.debian.org
Sat Nov 18 16:34:19 GMT 2023



Markus Koschany pushed to branch bullseye at Debian Java Maintainers / netty


Commits:
022f0e79 by Markus Koschany at 2023-11-18T15:31:40+01:00
Fix CVE-2023-34462 and CVE-2023-44487.

- - - - -
ebd3adfe by Markus Koschany at 2023-11-18T15:33:54+01:00
Update changelog

- - - - -
666b56cc by Markus Koschany at 2023-11-18T15:39:26+01:00
Fix FTBFS with new OpenJDK version.

- - - - -


5 changed files:

- debian/changelog
- + debian/patches/21-java-17.patch
- + debian/patches/CVE-2023-34462.patch
- + debian/patches/CVE-2023-44487.patch
- debian/patches/series


Changes:

=====================================
debian/changelog
=====================================
@@ -1,3 +1,15 @@
+netty (1:4.1.48-4+deb11u2) bullseye-security; urgency=high
+
+  * Team upload.
+  * Fix CVE-2023-34462: (Closes: #1038947)
+    Guard against high memory usage when parsing ClientHello messages.
+  * Fix CVE-2023-44487: (Closes: #1054234)
+    The HTTP/2 protocol allows a denial of service (server resource
+    consumption) because request cancellation can reset many streams quickly.
+  * Add 21-java-17.patch to fix a FTBFS with newer OpenJDK versions.
+
+ -- Markus Koschany <apo at debian.org>  Sat, 18 Nov 2023 15:32:05 +0100
+
 netty (1:4.1.48-4+deb11u1) bullseye-security; urgency=high
 
   * Team upload.


=====================================
debian/patches/21-java-17.patch
=====================================
@@ -0,0 +1,17 @@
+Description: compile with JDK 17
+Source: https://github.com/netty/netty/commit/bb184794341255cf02f9b7156c5ad828b172fdab.patch
+Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1011135
+Comment: No longer needed after updating upstream to 4.1.52 or later
+
+--- a/handler/src/main/java/io/netty/handler/ssl/util/OpenJdkSelfSignedCertGenerator.java
++++ b/handler/src/main/java/io/netty/handler/ssl/util/OpenJdkSelfSignedCertGenerator.java
+@@ -66,7 +66,8 @@
+         info.set(X509CertInfo.VALIDITY, new CertificateValidity(notBefore, notAfter));
+         info.set(X509CertInfo.KEY, new CertificateX509Key(keypair.getPublic()));
+         info.set(X509CertInfo.ALGORITHM_ID,
+-                new CertificateAlgorithmId(new AlgorithmId(AlgorithmId.sha256WithRSAEncryption_oid)));
++                // sha256WithRSAEncryption
++                new CertificateAlgorithmId(AlgorithmId.get("1.2.840.113549.1.1.11")));
+ 
+         // Sign the cert to identify the algorithm that's used.
+         X509CertImpl cert = new X509CertImpl(info);


=====================================
debian/patches/CVE-2023-34462.patch
=====================================
@@ -0,0 +1,277 @@
+From: Markus Koschany <apo at debian.org>
+Date: Sun, 5 Nov 2023 21:05:39 +0100
+Subject: CVE-2023-34462
+
+Bug-Debian: https://bugs.debian.org/1038947
+Origin: https://github.com/netty/netty/commit/535da17e45201ae4278c0479e6162bb4127d4c32
+---
+ .../java/io/netty/util/internal/ObjectUtil.java    | 55 ++++++++++++++++++++--
+ .../io/netty/handler/ssl/AbstractSniHandler.java   | 22 +++++++++
+ .../main/java/io/netty/handler/ssl/SniHandler.java | 50 ++++++++++++++++++++
+ .../netty/handler/ssl/SslClientHelloHandler.java   | 32 +++++++++++++
+ 4 files changed, 156 insertions(+), 3 deletions(-)
+
+diff --git a/common/src/main/java/io/netty/util/internal/ObjectUtil.java b/common/src/main/java/io/netty/util/internal/ObjectUtil.java
+index cbac561..ef26046 100644
+--- a/common/src/main/java/io/netty/util/internal/ObjectUtil.java
++++ b/common/src/main/java/io/netty/util/internal/ObjectUtil.java
+@@ -21,6 +21,11 @@ import java.util.Collection;
+  */
+ public final class ObjectUtil {
+ 
++    private static final float FLOAT_ZERO = 0.0F;
++    private static final double DOUBLE_ZERO = 0.0D;
++    private static final long LONG_ZERO = 0L;
++    private static final int INT_ZERO = 0;
++
+     private ObjectUtil() {
+     }
+ 
+@@ -72,13 +77,57 @@ public final class ObjectUtil {
+      * Checks that the given argument is positive or zero. If it is not, throws {@link IllegalArgumentException}.
+      * Otherwise, returns the argument.
+      */
+-    public static long checkPositiveOrZero(long i, String name) {
+-        if (i < 0) {
+-            throw new IllegalArgumentException(name + ": " + i + " (expected: >= 0)");
++    public static long checkPositiveOrZero(long l, String name) {
++        if (l < 0) {
++            throw new IllegalArgumentException(name + ": " + l + " (expected: >= 0)");
++        }
++        return l;
++    }
++
++     /**
++     * Checks that the given argument is positive or zero. If it is not, throws {@link IllegalArgumentException}.
++     * Otherwise, returns the argument.
++     */
++    public static double checkPositiveOrZero(final double d, final String name) {
++        if (d < DOUBLE_ZERO) {
++            throw new IllegalArgumentException(name + " : " + d + " (expected: >= 0)");
++        }
++        return d;
++    }
++
++    /**
++     * Checks that the given argument is positive or zero. If it is not, throws {@link IllegalArgumentException}.
++     * Otherwise, returns the argument.
++     */
++    public static float checkPositiveOrZero(final float f, final String name) {
++        if (f < FLOAT_ZERO) {
++            throw new IllegalArgumentException(name + " : " + f + " (expected: >= 0)");
++        }
++        return f;
++    }
++
++    /**
++     * Checks that the given argument is in range. If it is not, throws {@link IllegalArgumentException}.
++     * Otherwise, returns the argument.
++     */
++    public static int checkInRange(int i, int start, int end, String name) {
++        if (i < start || i > end) {
++            throw new IllegalArgumentException(name + ": " + i + " (expected: " + start + "-" + end + ")");
+         }
+         return i;
+     }
+ 
++    /**
++     * Checks that the given argument is in range. If it is not, throws {@link IllegalArgumentException}.
++     * Otherwise, returns the argument.
++     */
++    public static long checkInRange(long l, long start, long end, String name) {
++        if (l < start || l > end) {
++            throw new IllegalArgumentException(name + ": " + l + " (expected: " + start + "-" + end + ")");
++        }
++        return l;
++    }
++
+     /**
+      * Checks that the given argument is neither null nor empty.
+      * If it is, throws {@link NullPointerException} or {@link IllegalArgumentException}.
+diff --git a/handler/src/main/java/io/netty/handler/ssl/AbstractSniHandler.java b/handler/src/main/java/io/netty/handler/ssl/AbstractSniHandler.java
+index dcba585..02baad0 100644
+--- a/handler/src/main/java/io/netty/handler/ssl/AbstractSniHandler.java
++++ b/handler/src/main/java/io/netty/handler/ssl/AbstractSniHandler.java
+@@ -19,6 +19,7 @@ import io.netty.buffer.ByteBuf;
+ import io.netty.channel.ChannelHandlerContext;
+ import io.netty.util.CharsetUtil;
+ import io.netty.util.concurrent.Future;
++import static io.netty.util.internal.ObjectUtil.checkPositiveOrZero;
+ 
+ import java.util.Locale;
+ 
+@@ -117,8 +118,29 @@ public abstract class AbstractSniHandler<T> extends SslClientHelloHandler<T> {
+         return null;
+     }
+ 
++    protected final long handshakeTimeoutMillis;
+     private String hostname;
+ 
++    /**
++     * @param handshakeTimeoutMillis    the handshake timeout in milliseconds
++     */
++    protected AbstractSniHandler(long handshakeTimeoutMillis) {
++        this(0, handshakeTimeoutMillis);
++    }
++
++    /**
++     * @paramm maxClientHelloLength     the maximum length of the client hello message.
++     * @param handshakeTimeoutMillis    the handshake timeout in milliseconds
++     */
++    protected AbstractSniHandler(int maxClientHelloLength, long handshakeTimeoutMillis) {
++        super(maxClientHelloLength);
++        this.handshakeTimeoutMillis = checkPositiveOrZero(handshakeTimeoutMillis, "handshakeTimeoutMillis");
++    }
++
++    public AbstractSniHandler() {
++        this(0, 0L);
++    }
++
+     @Override
+     protected Future<T> lookup(ChannelHandlerContext ctx, ByteBuf clientHello) throws Exception {
+         hostname = clientHello == null ? null : extractSniHostname(clientHello);
+diff --git a/handler/src/main/java/io/netty/handler/ssl/SniHandler.java b/handler/src/main/java/io/netty/handler/ssl/SniHandler.java
+index c6a8227..f5e9589 100644
+--- a/handler/src/main/java/io/netty/handler/ssl/SniHandler.java
++++ b/handler/src/main/java/io/netty/handler/ssl/SniHandler.java
+@@ -51,6 +51,19 @@ public class SniHandler extends AbstractSniHandler<SslContext> {
+         this(new AsyncMappingAdapter(mapping));
+     }
+ 
++    /**
++     * Creates a SNI detection handler with configured {@link SslContext}
++     * maintained by {@link Mapping}
++     *
++     * @param mapping the mapping of domain name to {@link SslContext}
++     * @param maxClientHelloLength the maximum length of the client hello message
++     * @param handshakeTimeoutMillis the handshake timeout in milliseconds
++     */
++    public SniHandler(Mapping<? super String, ? extends SslContext> mapping,
++                      int maxClientHelloLength, long handshakeTimeoutMillis) {
++        this(new AsyncMappingAdapter(mapping), maxClientHelloLength, handshakeTimeoutMillis);
++    }
++
+     /**
+      * Creates a SNI detection handler with configured {@link SslContext}
+      * maintained by {@link DomainNameMapping}
+@@ -69,9 +82,46 @@ public class SniHandler extends AbstractSniHandler<SslContext> {
+      */
+     @SuppressWarnings("unchecked")
+     public SniHandler(AsyncMapping<? super String, ? extends SslContext> mapping) {
++        this(mapping, 0, 0L);
++    }
++
++    /**
++     * Creates a SNI detection handler with configured {@link SslContext}
++     * maintained by {@link AsyncMapping}
++     *
++     * @param mapping the mapping of domain name to {@link SslContext}
++     * @param maxClientHelloLength the maximum length of the client hello message
++     * @param handshakeTimeoutMillis the handshake timeout in milliseconds
++     */
++    @SuppressWarnings("unchecked")
++    public SniHandler(AsyncMapping<? super String, ? extends SslContext> mapping,
++                      int maxClientHelloLength, long handshakeTimeoutMillis) {
++        super(maxClientHelloLength, handshakeTimeoutMillis);
+         this.mapping = (AsyncMapping<String, SslContext>) ObjectUtil.checkNotNull(mapping, "mapping");
+     }
+ 
++    /**
++     * Creates a SNI detection handler with configured {@link SslContext}
++     * maintained by {@link Mapping}
++     *
++     * @param mapping the mapping of domain name to {@link SslContext}
++     * @param handshakeTimeoutMillis the handshake timeout in milliseconds
++     */
++    public SniHandler(Mapping<? super String, ? extends SslContext> mapping, long handshakeTimeoutMillis) {
++        this(new AsyncMappingAdapter(mapping), handshakeTimeoutMillis);
++    }
++
++    /**
++     * Creates a SNI detection handler with configured {@link SslContext}
++     * maintained by {@link AsyncMapping}
++     *
++     * @param mapping the mapping of domain name to {@link SslContext}
++     * @param handshakeTimeoutMillis the handshake timeout in milliseconds
++     */
++    public SniHandler(AsyncMapping<? super String, ? extends SslContext> mapping, long handshakeTimeoutMillis) {
++        this(mapping, 0, handshakeTimeoutMillis);
++    }
++
+     /**
+      * @return the selected hostname
+      */
+diff --git a/handler/src/main/java/io/netty/handler/ssl/SslClientHelloHandler.java b/handler/src/main/java/io/netty/handler/ssl/SslClientHelloHandler.java
+index 4bcf349..8ef0069 100644
+--- a/handler/src/main/java/io/netty/handler/ssl/SslClientHelloHandler.java
++++ b/handler/src/main/java/io/netty/handler/ssl/SslClientHelloHandler.java
+@@ -22,8 +22,10 @@ import io.netty.channel.ChannelOutboundHandler;
+ import io.netty.channel.ChannelPromise;
+ import io.netty.handler.codec.ByteToMessageDecoder;
+ import io.netty.handler.codec.DecoderException;
++import io.netty.handler.codec.TooLongFrameException;
+ import io.netty.util.concurrent.Future;
+ import io.netty.util.concurrent.FutureListener;
++import io.netty.util.internal.ObjectUtil;
+ import io.netty.util.internal.PlatformDependent;
+ import io.netty.util.internal.logging.InternalLogger;
+ import io.netty.util.internal.logging.InternalLoggerFactory;
+@@ -36,14 +38,32 @@ import java.util.List;
+  */
+ public abstract class SslClientHelloHandler<T> extends ByteToMessageDecoder implements ChannelOutboundHandler {
+ 
++    /**
++     * The maximum length of client hello message as defined by
++     * <a href="https://www.rfc-editor.org/rfc/rfc5246#section-6.2.1">RFC5246</a>.
++     */
++    public static final int MAX_CLIENT_HELLO_LENGTH = 0xFFFFFF;
++
+     private static final InternalLogger logger =
+             InternalLoggerFactory.getInstance(SslClientHelloHandler.class);
+ 
++    private final int maxClientHelloLength;
+     private boolean handshakeFailed;
+     private boolean suppressRead;
+     private boolean readPending;
+     private ByteBuf handshakeBuffer;
+ 
++    public SslClientHelloHandler() {
++        this(MAX_CLIENT_HELLO_LENGTH);
++    }
++
++    protected SslClientHelloHandler(int maxClientHelloLength) {
++        // 16MB is the maximum as per RFC:
++        // See https://www.rfc-editor.org/rfc/rfc5246#section-6.2.1
++        this.maxClientHelloLength =
++                ObjectUtil.checkInRange(maxClientHelloLength, 0, MAX_CLIENT_HELLO_LENGTH, "maxClientHelloLength");
++    }
++
+     @Override
+     protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
+         if (!suppressRead && !handshakeFailed) {
+@@ -117,6 +137,15 @@ public abstract class SslClientHelloHandler<T> extends ByteToMessageDecoder impl
+                                     handshakeLength = in.getUnsignedMedium(readerIndex +
+                                             SslUtils.SSL_RECORD_HEADER_LENGTH + 1);
+ 
++                                    if (handshakeLength > maxClientHelloLength && maxClientHelloLength != 0) {
++                                        TooLongFrameException e = new TooLongFrameException(
++                                                "ClientHello length exceeds " + maxClientHelloLength +
++                                                        ": " + handshakeLength);
++                                        in.skipBytes(in.readableBytes());
++                                        ctx.fireUserEventTriggered(new SniCompletionEvent(e));
++                                        SslUtils.handleHandshakeFailure(ctx, e, true);
++                                        throw e;
++                                    }
+                                     // Consume handshakeType and handshakeLength (this sums up as 4 bytes)
+                                     readerIndex += 4;
+                                     packetLength -= 4;
+@@ -161,6 +190,9 @@ public abstract class SslClientHelloHandler<T> extends ByteToMessageDecoder impl
+             } catch (NotSslRecordException e) {
+                 // Just rethrow as in this case we also closed the channel and this is consistent with SslHandler.
+                 throw e;
++            } catch (TooLongFrameException e) {
++                // Just rethrow as in this case we also closed the channel
++                throw e;
+             } catch (Exception e) {
+                 // unexpected encoding, ignore sni and use default
+                 if (logger.isDebugEnabled()) {


=====================================
debian/patches/CVE-2023-44487.patch
=====================================
@@ -0,0 +1,241 @@
+From: Markus Koschany <apo at debian.org>
+Date: Sun, 5 Nov 2023 22:29:58 +0100
+Subject: CVE-2023-44487
+
+Bug-Debian: https://bugs.debian.org/1054234
+Origin: https://github.com/netty/netty/commit/58f75f665aa81a8cbcf6ffa74820042a285c5e61
+---
+ .../AbstractHttp2ConnectionHandlerBuilder.java     | 24 ++++++++-
+ .../codec/http2/Http2FrameCodecBuilder.java        |  6 +++
+ .../codec/http2/Http2MaxRstFrameDecoder.java       | 58 ++++++++++++++++++++++
+ .../codec/http2/Http2MaxRstFrameListener.java      | 58 ++++++++++++++++++++++
+ .../codec/http2/Http2MultiplexCodecBuilder.java    |  6 +++
+ 5 files changed, 150 insertions(+), 2 deletions(-)
+ create mode 100644 codec-http2/src/main/java/io/netty/handler/codec/http2/Http2MaxRstFrameDecoder.java
+ create mode 100644 codec-http2/src/main/java/io/netty/handler/codec/http2/Http2MaxRstFrameListener.java
+
+diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/AbstractHttp2ConnectionHandlerBuilder.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/AbstractHttp2ConnectionHandlerBuilder.java
+index f262b11..a904310 100644
+--- a/codec-http2/src/main/java/io/netty/handler/codec/http2/AbstractHttp2ConnectionHandlerBuilder.java
++++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/AbstractHttp2ConnectionHandlerBuilder.java
+@@ -109,6 +109,8 @@ public abstract class AbstractHttp2ConnectionHandlerBuilder<T extends Http2Conne
+     private boolean autoAckPingFrame = true;
+     private int maxQueuedControlFrames = Http2CodecUtil.DEFAULT_MAX_QUEUED_CONTROL_FRAMES;
+     private int maxConsecutiveEmptyFrames = 2;
++    private int maxRstFramesPerWindow = 200;
++    private int secondsPerWindow = 30;
+ 
+     /**
+      * Sets the {@link Http2Settings} to use for the initial connection settings exchange.
+@@ -410,7 +412,7 @@ public abstract class AbstractHttp2ConnectionHandlerBuilder<T extends Http2Conne
+ 
+     /**
+      * Returns the maximum number of consecutive empty DATA frames (without end_of_stream flag) that are allowed before
+-     * the connection is closed. This allows to protected against the remote peer flooding us with such frames and
++     * the connection is closed. This allows to protect against the remote peer flooding us with such frames and
+      * so use up a lot of CPU. There is no valid use-case for empty DATA frames without end_of_stream flag.
+      *
+      * {@code 0} means no protection is in place.
+@@ -421,7 +423,7 @@ public abstract class AbstractHttp2ConnectionHandlerBuilder<T extends Http2Conne
+ 
+     /**
+      * Sets the maximum number of consecutive empty DATA frames (without end_of_stream flag) that are allowed before
+-     * the connection is closed. This allows to protected against the remote peer flooding us with such frames and
++     * the connection is closed. This allows to protect against the remote peer flooding us with such frames and
+      * so use up a lot of CPU. There is no valid use-case for empty DATA frames without end_of_stream flag.
+      *
+      * {@code 0} means no protection should be applied.
+@@ -433,6 +435,21 @@ public abstract class AbstractHttp2ConnectionHandlerBuilder<T extends Http2Conne
+         return self();
+     }
+ 
++    /**
++     * Sets the maximum number RST frames that are allowed per window before
++     * the connection is closed. This allows to protect against the remote peer flooding us with such frames and
++     * so use up a lot of CPU.
++     *
++     * {@code 0} for any of the parameters means no protection should be applied.
++     */
++    protected B decoderEnforceMaxRstFramesPerWindow(int maxRstFramesPerWindow, int secondsPerWindow) {
++        enforceNonCodecConstraints("decoderEnforceMaxRstFramesPerWindow");
++        this.maxRstFramesPerWindow = checkPositiveOrZero(
++                maxRstFramesPerWindow, "maxRstFramesPerWindow");
++        this.secondsPerWindow = checkPositiveOrZero(secondsPerWindow, "secondsPerWindow");
++        return self();
++    }
++
+     /**
+      * Determine if settings frame should automatically be acknowledged and applied.
+      * @return this.
+@@ -545,6 +562,9 @@ public abstract class AbstractHttp2ConnectionHandlerBuilder<T extends Http2Conne
+         if (maxConsecutiveEmptyDataFrames > 0) {
+             decoder = new Http2EmptyDataFrameConnectionDecoder(decoder, maxConsecutiveEmptyDataFrames);
+         }
++        if (maxRstFramesPerWindow > 0 && secondsPerWindow > 0) {
++            decoder = new Http2MaxRstFrameDecoder(decoder, maxRstFramesPerWindow, secondsPerWindow);
++        }
+         final T handler;
+         try {
+             // Call the abstract build method
+diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2FrameCodecBuilder.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2FrameCodecBuilder.java
+index fad31b2..241c9c5 100644
+--- a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2FrameCodecBuilder.java
++++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2FrameCodecBuilder.java
+@@ -177,6 +177,12 @@ public class Http2FrameCodecBuilder extends
+         return super.decoderEnforceMaxConsecutiveEmptyDataFrames(maxConsecutiveEmptyFrames);
+     }
+ 
++    @Override
++    public Http2FrameCodecBuilder decoderEnforceMaxRstFramesPerWindow(
++            int maxConsecutiveEmptyFrames, int secondsPerWindow) {
++        return super.decoderEnforceMaxRstFramesPerWindow(maxConsecutiveEmptyFrames, secondsPerWindow);
++    }
++
+     /**
+      * Build a {@link Http2FrameCodec} object.
+      */
+diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2MaxRstFrameDecoder.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2MaxRstFrameDecoder.java
+new file mode 100644
+index 0000000..6ac6660
+--- /dev/null
++++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2MaxRstFrameDecoder.java
+@@ -0,0 +1,58 @@
++/*
++ * Copyright 2023 The Netty Project
++ *
++ * The Netty Project 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:
++ *
++ *   https://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 io.netty.handler.codec.http2;
++
++import static io.netty.util.internal.ObjectUtil.checkPositive;
++
++
++/**
++ * Enforce a limit on the maximum number of RST frames that are allowed per a window
++ * before the connection will be closed with a GO_AWAY frame.
++ */
++final class Http2MaxRstFrameDecoder extends DecoratingHttp2ConnectionDecoder {
++    private final int maxRstFramesPerWindow;
++    private final int secondsPerWindow;
++
++    Http2MaxRstFrameDecoder(Http2ConnectionDecoder delegate, int maxRstFramesPerWindow, int secondsPerWindow) {
++        super(delegate);
++        this.maxRstFramesPerWindow = checkPositive(maxRstFramesPerWindow, "maxRstFramesPerWindow");
++        this.secondsPerWindow = checkPositive(secondsPerWindow, "secondsPerWindow");
++    }
++
++    @Override
++    public void frameListener(Http2FrameListener listener) {
++        if (listener != null) {
++            super.frameListener(new Http2MaxRstFrameListener(listener, maxRstFramesPerWindow, secondsPerWindow));
++        } else {
++            super.frameListener(null);
++        }
++    }
++
++    @Override
++    public Http2FrameListener frameListener() {
++        Http2FrameListener frameListener = frameListener0();
++        // Unwrap the original Http2FrameListener as we add this decoder under the hood.
++        if (frameListener instanceof Http2MaxRstFrameListener) {
++            return ((Http2MaxRstFrameListener) frameListener).listener;
++        }
++        return frameListener;
++    }
++
++    // Package-private for testing
++    Http2FrameListener frameListener0() {
++        return super.frameListener();
++    }
++}
+diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2MaxRstFrameListener.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2MaxRstFrameListener.java
+new file mode 100644
+index 0000000..4603686
+--- /dev/null
++++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2MaxRstFrameListener.java
+@@ -0,0 +1,58 @@
++/*
++ * Copyright 2023 The Netty Project
++ *
++ * The Netty Project 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:
++ *
++ *   https://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 io.netty.handler.codec.http2;
++
++import io.netty.channel.ChannelHandlerContext;
++import io.netty.util.internal.logging.InternalLogger;
++import io.netty.util.internal.logging.InternalLoggerFactory;
++
++import java.util.concurrent.TimeUnit;
++
++
++final class Http2MaxRstFrameListener extends Http2FrameListenerDecorator {
++    private static final InternalLogger logger = InternalLoggerFactory.getInstance(Http2MaxRstFrameListener.class);
++
++    private final long nanosPerWindow;
++    private final int maxRstFramesPerWindow;
++    private long lastRstFrameNano = System.nanoTime();
++    private int receivedRstInWindow;
++
++    Http2MaxRstFrameListener(Http2FrameListener listener, int maxRstFramesPerWindow, int secondsPerWindow) {
++        super(listener);
++        this.maxRstFramesPerWindow = maxRstFramesPerWindow;
++        this.nanosPerWindow = TimeUnit.SECONDS.toNanos(secondsPerWindow);
++    }
++
++    @Override
++    public void onRstStreamRead(ChannelHandlerContext ctx, int streamId, long errorCode) throws Http2Exception {
++        long currentNano = System.nanoTime();
++        if (currentNano - lastRstFrameNano >= nanosPerWindow) {
++            lastRstFrameNano = currentNano;
++            receivedRstInWindow = 1;
++        } else {
++            receivedRstInWindow++;
++            if (receivedRstInWindow > maxRstFramesPerWindow) {
++                Http2Exception exception = Http2Exception.connectionError(Http2Error.ENHANCE_YOUR_CALM,
++                        "Maximum number of RST frames reached");
++                logger.debug("{} Maximum number {} of RST frames reached within {} seconds, " +
++                                "closing connection with {} error", ctx.channel(), maxRstFramesPerWindow,
++                        TimeUnit.NANOSECONDS.toSeconds(nanosPerWindow), exception.error(), exception);
++                throw exception;
++            }
++        }
++        super.onRstStreamRead(ctx, streamId, errorCode);
++    }
++}
+diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2MultiplexCodecBuilder.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2MultiplexCodecBuilder.java
+index 5d0829e..a3c0bed 100644
+--- a/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2MultiplexCodecBuilder.java
++++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/Http2MultiplexCodecBuilder.java
+@@ -206,6 +206,12 @@ public class Http2MultiplexCodecBuilder
+         return super.decoderEnforceMaxConsecutiveEmptyDataFrames(maxConsecutiveEmptyFrames);
+     }
+ 
++    @Override
++    public Http2MultiplexCodecBuilder decoderEnforceMaxRstFramesPerWindow(
++            int maxConsecutiveEmptyFrames, int secondsPerWindow) {
++        return super.decoderEnforceMaxRstFramesPerWindow(maxConsecutiveEmptyFrames, secondsPerWindow);
++    }
++
+     @Override
+     public Http2MultiplexCodec build() {
+         Http2FrameWriter frameWriter = this.frameWriter;


=====================================
debian/patches/series
=====================================
@@ -20,3 +20,6 @@ CVE-2021-37137.patch
 CVE-2021-43797.patch
 CVE-2022-41881.patch
 CVE-2022-41915.patch
+CVE-2023-34462.patch
+CVE-2023-44487.patch
+21-java-17.patch



View it on GitLab: https://salsa.debian.org/java-team/netty/-/compare/cd2a88391d2c003ba4846b2344d66e0e575031be...666b56cc6423680f7d43a720f8d2b495067845d0

-- 
View it on GitLab: https://salsa.debian.org/java-team/netty/-/compare/cd2a88391d2c003ba4846b2344d66e0e575031be...666b56cc6423680f7d43a720f8d2b495067845d0
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-java-commits/attachments/20231118/5779a864/attachment.htm>


More information about the pkg-java-commits mailing list