This is an automated email from the ASF dual-hosted git repository.

rmaucher pushed a commit to branch 11.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/11.0.x by this push:
     new 4487aa9dd4 Avoid some overflow and bounds check scenarios
4487aa9dd4 is described below

commit 4487aa9dd41ed7176cf0d054f5f6dda97c81d0c8
Author: remm <[email protected]>
AuthorDate: Fri May 22 11:51:31 2026 +0200

    Avoid some overflow and bounds check scenarios
    
    Coauthored by OpenCode.
---
 java/org/apache/tomcat/util/buf/Asn1Parser.java     | 21 +++++++++++++++++++--
 java/org/apache/tomcat/util/buf/Asn1Writer.java     |  4 ++++
 .../apache/tomcat/util/buf/LocalStrings.properties  |  1 +
 webapps/docs/changelog.xml                          |  3 +++
 4 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/java/org/apache/tomcat/util/buf/Asn1Parser.java 
b/java/org/apache/tomcat/util/buf/Asn1Parser.java
index 0c0d27c0c8..103f46d904 100644
--- a/java/org/apache/tomcat/util/buf/Asn1Parser.java
+++ b/java/org/apache/tomcat/util/buf/Asn1Parser.java
@@ -145,7 +145,7 @@ public class Asn1Parser {
      */
     public void parseFullLength() {
         int len = parseLength();
-        if (len + pos != source.length) {
+        if (source.length - pos != len) {
             throw new 
IllegalArgumentException(sm.getString("asn1Parser.lengthInvalid", 
Integer.valueOf(len),
                     Integer.valueOf(source.length - pos)));
         }
@@ -161,11 +161,19 @@ public class Asn1Parser {
         int len = next();
         if (len > 127) {
             int bytes = len - 128;
+            if (bytes > 4) {
+                throw new 
IllegalArgumentException(sm.getString("asn1Parser.lengthInvalid", 
Integer.valueOf(-1),
+                        Integer.valueOf(source.length - pos)));
+            }
             len = 0;
             for (int i = 0; i < bytes; i++) {
                 len = len << 8;
                 len = len + next();
             }
+            if (len < 0) {
+                throw new 
IllegalArgumentException(sm.getString("asn1Parser.lengthInvalid", 
Integer.valueOf(-1),
+                        Integer.valueOf(source.length - pos)));
+            }
         }
         /*
          * If this is the first length parsed after a sequence has been added 
to the sequence nesting tracking mechanism
@@ -174,6 +182,10 @@ public class Asn1Parser {
          */
         if (nestedSequenceEndPositions.peekLast() != null && 
nestedSequenceEndPositions.peekLast().intValue() == -1) {
             nestedSequenceEndPositions.pollLast();
+            if (source.length - pos < len) {
+                throw new 
IllegalArgumentException(sm.getString("asn1Parser.lengthInvalid", 
Integer.valueOf(-1),
+                        Integer.valueOf(source.length - pos)));
+            }
             nestedSequenceEndPositions.addLast(Integer.valueOf(pos + len));
         }
         return len;
@@ -245,7 +257,12 @@ public class Asn1Parser {
         parseTag(tag);
         int len = parseLength();
         byte[] result = new byte[len];
-        System.arraycopy(source, pos, result, 0, result.length);
+        if (pos + result.length <= source.length) {
+            System.arraycopy(source, pos, result, 0, result.length);
+        } else {
+            throw new 
IllegalArgumentException(sm.getString("asn1Parser.truncatedData", 
Integer.valueOf(result.length),
+                    Integer.valueOf(source.length - pos)));
+        }
         pos += result.length;
         return result;
     }
diff --git a/java/org/apache/tomcat/util/buf/Asn1Writer.java 
b/java/org/apache/tomcat/util/buf/Asn1Writer.java
index ce95e9fa5a..d6f68363c8 100644
--- a/java/org/apache/tomcat/util/buf/Asn1Writer.java
+++ b/java/org/apache/tomcat/util/buf/Asn1Writer.java
@@ -57,6 +57,10 @@ public class Asn1Writer {
      * @return the DER-encoded INTEGER bytes
      */
     public static byte[] writeInteger(int value) {
+        if (value < 0) {
+            throw new IllegalArgumentException();
+        }
+
         // How many bytes required to write the value? No more than 4 for int.
         int valueSize = 1;
         while ((value >> (valueSize * 8)) > 0) {
diff --git a/java/org/apache/tomcat/util/buf/LocalStrings.properties 
b/java/org/apache/tomcat/util/buf/LocalStrings.properties
index cbef1ff927..bd4ec591f7 100644
--- a/java/org/apache/tomcat/util/buf/LocalStrings.properties
+++ b/java/org/apache/tomcat/util/buf/LocalStrings.properties
@@ -18,6 +18,7 @@
 
 asn1Parser.lengthInvalid=Invalid length [{0}] bytes reported when the input 
data length is [{1}] bytes
 asn1Parser.tagMismatch=Expected to find value [{0}] but found value [{1}]
+asn1Parser.truncatedData=Need [{0}] bytes but only [{1}] are available
 
 b2cConverter.decoderResetFail=Failed to reset instance of decoder for 
character set [{0}]
 b2cConverter.unknownEncoding=The character encoding [{0}] is not supported
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index c092e622ad..7fe98c8be0 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -209,6 +209,9 @@
         Call the delegate key manager in JSSE to retrieve the server key.
         (remm)
       </fix>
+      <fix>
+        Avoid overflow scenarios in Asn1Parser. (remm)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Jasper">


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to