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

asf-gitbox-commits pushed a commit to branch 2.1.X
in repository https://gitbox.apache.org/repos/asf/mina.git


The following commit(s) were added to refs/heads/2.1.X by this push:
     new 3166d262d Applied the fix for the CVE-2026-47065 that wasn't back 
ported by mistake. Also added a protection against concurrent access of the 
selector
3166d262d is described below

commit 3166d262de1e7027a360ebb85732dbf861b1eea7
Author: emmanuel lecharny <[email protected]>
AuthorDate: Sat Jun 20 16:06:50 2026 +0200

    Applied the fix for the CVE-2026-47065 that wasn't back ported by mistake. 
Also added a protection against concurrent access of the selector
---
 .../apache/mina/core/buffer/AbstractIoBuffer.java  | 24 ++++++++++++++++++++
 .../mina/transport/socket/nio/NioProcessor.java    | 26 +++++++++++++++++++---
 2 files changed, 47 insertions(+), 3 deletions(-)

diff --git 
a/mina-core/src/main/java/org/apache/mina/core/buffer/AbstractIoBuffer.java 
b/mina-core/src/main/java/org/apache/mina/core/buffer/AbstractIoBuffer.java
index f5aa45b99..2fb4cdf89 100644
--- a/mina-core/src/main/java/org/apache/mina/core/buffer/AbstractIoBuffer.java
+++ b/mina-core/src/main/java/org/apache/mina/core/buffer/AbstractIoBuffer.java
@@ -28,6 +28,7 @@ import java.io.ObjectStreamClass;
 import java.io.OutputStream;
 import java.io.Serializable;
 import java.io.StreamCorruptedException;
+import java.lang.reflect.Proxy;
 import java.nio.BufferOverflowException;
 import java.nio.BufferUnderflowException;
 import java.nio.ByteBuffer;
@@ -2213,6 +2214,29 @@ public abstract class AbstractIoBuffer extends IoBuffer {
                     return super.resolveClass(desc);
                 }
             }
+            
+            @Override
+            protected Class<?> resolveProxyClass(String[] interfaces) throws 
IOException, ClassNotFoundException {
+                Class<?>[] classes = new Class<?>[interfaces.length];
+                int i = 0;
+
+                for (String interfaceName : interfaces) {
+                    // Apply the acceptMatchers filter to EVERY proxy 
interface name before
+                    // any Class.forName() call. The JDK default 
resolveProxyClass() bypasses
+                    // resolveClass()/readClassDescriptor() entirely, so 
without this override
+                    // an attacker can deserialize a java.lang.reflect.Proxy 
implementing
+                    // arbitrary interfaces regardless of the configured 
allow-list.
+                    if (!acceptMatchers.stream().anyMatch(m -> 
m.matches(interfaceName))) {
+                        throw new ClassNotFoundException("Interface not in 
accept list " + interfaceName);
+                    }
+
+                    // Use Class.forName(name, false, loader) - 
initialize=false - and load via
+                    // the configured classLoader, NOT 
latestUserDefinedLoader().
+                    classes[i++] = Class.forName(interfaceName, false, 
classLoader);
+                }
+
+                return Proxy.getProxyClass(classLoader, classes);
+            }
         }) {
             return in.readObject();
         } catch (IOException e) {
diff --git 
a/mina-core/src/main/java/org/apache/mina/transport/socket/nio/NioProcessor.java
 
b/mina-core/src/main/java/org/apache/mina/transport/socket/nio/NioProcessor.java
index 1dc8d2efe..5a6385b46 100644
--- 
a/mina-core/src/main/java/org/apache/mina/transport/socket/nio/NioProcessor.java
+++ 
b/mina-core/src/main/java/org/apache/mina/transport/socket/nio/NioProcessor.java
@@ -163,7 +163,13 @@ public class NioProcessor extends 
AbstractPollingIoProcessor<NioSession> {
     @Override
     protected int allSessionsCount()
     {
-        return selector.keys().size();
+        selectorLock.readLock().lock();
+        
+        try {
+            return selector.keys().size();
+        } finally {
+            selectorLock.readLock().unlock();
+        }
     }
 
     @SuppressWarnings("synthetic-access")
@@ -345,7 +351,14 @@ public class NioProcessor extends 
AbstractPollingIoProcessor<NioSession> {
         }
 
         if (oldInterestOps != newInterestOps) {
-            key.interestOps(newInterestOps);
+            // Protect the selector against concurrent accesses
+            selectorLock.readLock().lock();
+            
+            try {
+                key.interestOps(newInterestOps);
+            } finally {
+                selectorLock.readLock().unlock();
+            }
         }
     }
 
@@ -368,7 +381,14 @@ public class NioProcessor extends 
AbstractPollingIoProcessor<NioSession> {
             newInterestOps &= ~SelectionKey.OP_WRITE;
         }
 
-        key.interestOps(newInterestOps);
+        // Protect the selector against concurrent accesses
+        selectorLock.readLock().lock();
+        
+        try {
+            key.interestOps(newInterestOps);
+        } finally {
+            selectorLock.readLock().unlock();
+        }
     }
 
     @Override

Reply via email to