This is an automated email from the ASF dual-hosted git repository.
markt-asf pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/10.1.x by this push:
new ebf20995c3 Improve frame validation - make sure more serious errors
take priority
ebf20995c3 is described below
commit ebf20995c3c1dd525e96996c06d47d775be6b95d
Author: Mark Thomas <[email protected]>
AuthorDate: Mon Oct 26 23:13:57 2026 +0000
Improve frame validation - make sure more serious errors take priority
---
java/org/apache/coyote/http2/Http2AsyncParser.java | 8 ++++++++
java/org/apache/coyote/http2/Http2Parser.java | 15 +++++++++++----
java/org/apache/tomcat/websocket/WsSession.java | 4 ++--
webapps/docs/changelog.xml | 4 ++++
4 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/java/org/apache/coyote/http2/Http2AsyncParser.java
b/java/org/apache/coyote/http2/Http2AsyncParser.java
index 1615ec7cc7..473a78c996 100644
--- a/java/org/apache/coyote/http2/Http2AsyncParser.java
+++ b/java/org/apache/coyote/http2/Http2AsyncParser.java
@@ -232,6 +232,14 @@ class Http2AsyncParser extends Http2Parser {
}
if (payload.position() < payloadSize) {
+ /*
+ * If the payload is larger than the buffer provided to read
it, the read can never complete. Once all
+ * of the buffers are full, further reads return zero bytes
which, if continued, results in an endless
+ * read loop. validateFrame() above should already have
rejected such a frame.
+ */
+ if (payloadSize > payload.capacity()) {
+ return CompletionHandlerCall.DONE;
+ }
return CompletionHandlerCall.CONTINUE;
}
diff --git a/java/org/apache/coyote/http2/Http2Parser.java
b/java/org/apache/coyote/http2/Http2Parser.java
index 08a894f348..b05f868a30 100644
--- a/java/org/apache/coyote/http2/Http2Parser.java
+++ b/java/org/apache/coyote/http2/Http2Parser.java
@@ -738,10 +738,11 @@ class Http2Parser {
Integer.toString(flags), Integer.toString(payloadSize)));
}
- if (expected != null && frameType != expected) {
- throw new
StreamException(sm.getString("http2Parser.processFrame.unexpectedType",
expected, frameType),
- Http2Error.PROTOCOL_ERROR, streamId);
- }
+ /*
+ * Frames with multiple errors may trigger multiple failures. Check
the things that can trigger the more serious
+ * ConnectionException first so such errors are not masked by a less
serious error that triggers a
+ * StreamException.
+ */
int maxFrameSize = input.getMaxFrameSize();
if (payloadSize > maxFrameSize) {
@@ -764,7 +765,13 @@ class Http2Parser {
}
}
+ // May throw StreamException or ConnectionException
frameType.check(streamId, payloadSize);
+
+ if (expected != null && frameType != expected) {
+ throw new
StreamException(sm.getString("http2Parser.processFrame.unexpectedType",
expected, frameType),
+ Http2Error.PROTOCOL_ERROR, streamId);
+ }
}
diff --git a/java/org/apache/tomcat/websocket/WsSession.java
b/java/org/apache/tomcat/websocket/WsSession.java
index c35e4e2609..689dbce6ba 100644
--- a/java/org/apache/tomcat/websocket/WsSession.java
+++ b/java/org/apache/tomcat/websocket/WsSession.java
@@ -859,8 +859,8 @@ public class WsSession implements Session {
* endpoint.
*/
private Object getManagedEndpointInstance() {
- if (localEndpoint instanceof PojoEndpointBase pojoEndpoint) {
- Object pojo = pojoEndpoint.getPojo();
+ if (localEndpoint instanceof PojoEndpointBase) {
+ Object pojo = ((PojoEndpointBase) localEndpoint).getPojo();
if (pojo != null) {
return pojo;
}
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index b6c6589180..d353b3c858 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -549,6 +549,10 @@
suffixed certificate is used instead.
(dsoumis)
</update>
+ <fix>
+ When validating HTTP/2 frames, make sure more serious errors take
+ priority over less serious errors. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Jasper">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]