directory-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From elecha...@apache.org
Subject svn commit: r722296 - in /directory/shared/branches/shared-mina2: asn1/src/main/java/org/apache/directory/shared/asn1/ber/ ldap/src/main/java/org/apache/directory/shared/ldap/codec/ ldap/src/main/java/org/apache/directory/shared/ldap/message/ ldap/src/...
Date Mon, 01 Dec 2008 23:59:33 GMT
Author: elecharny
Date: Mon Dec  1 15:59:32 2008
New Revision: 722296

URL: http://svn.apache.org/viewvc?rev=722296&view=rev
Log:
Added all the needed code to handle the OOM protection, by limitating the PDU size.

The current limit is Integer.MAX_VALUE.

Modified:
    directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/AbstractContainer.java
    directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/Asn1Decoder.java
    directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/IAsn1Container.java
    directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapMessageContainer.java
    directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixDecoder.java
    directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixProvider.java
    directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/message/MessageDecoder.java
    directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/message/spi/Provider.java

Modified: directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/AbstractContainer.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/AbstractContainer.java?rev=722296&r1=722295&r2=722296&view=diff
==============================================================================
--- directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/AbstractContainer.java
(original)
+++ directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/AbstractContainer.java
Mon Dec  1 15:59:32 2008
@@ -63,6 +63,12 @@
     /** The grammar end transition flag */
     protected boolean grammarEndAllowed;
 
+    /** A counter for the decoded bytes */
+    protected int decodeBytes;
+
+    /** The maximum allowed size for a PDU. Default to MAX int value */
+    protected int maxPDUSize = Integer.MAX_VALUE;
+
     /** The incremental id used to tag TLVs */
     private int id = 0;
     
@@ -229,4 +235,52 @@
     {
         return tlv.getId();
     }
+
+
+    /**
+     * @return The number of decoded bytes for this message. This is used
+     * to control the PDU size and avoid PDU exceeding the maximum allowed
+     * size to break the server.
+     */
+    public int getDecodeBytes()
+    {
+        return decodeBytes;
+    }
+
+
+    /**
+     * Increment the decodedBytes by the latest received buffer's size.
+     * @param nb The buffer size.
+     */
+    public void incrementDecodeBytes( int nb )
+    {
+        decodeBytes += nb;
+    }
+    
+    
+    /**
+     * @return The maximum PDU size.
+     */
+    public int getMaxPDUSize()
+    {
+        return maxPDUSize;
+    }
+    
+    
+    /**
+     * Set the maximum PDU size.
+     * @param maxPDUSize The maximum PDU size (if negative or null, will be
+     * replaced by the max integer value)
+     */
+    public void setMaxPDUSize( int maxPDUSize )
+    {
+        if ( maxPDUSize > 0 )
+        {
+            this.maxPDUSize = maxPDUSize;
+        }
+        else
+        {
+            this.maxPDUSize = Integer.MAX_VALUE;
+        }
+    }
 }

Modified: directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/Asn1Decoder.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/Asn1Decoder.java?rev=722296&r1=722295&r2=722296&view=diff
==============================================================================
--- directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/Asn1Decoder.java
(original)
+++ directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/Asn1Decoder.java
Mon Dec  1 15:59:32 2008
@@ -47,10 +47,10 @@
     // -----------------------------------------------------------------
 
     /** The logger */
-    private static final Logger log = LoggerFactory.getLogger( Asn1Decoder.class );
+    private static final Logger LOG = LoggerFactory.getLogger( Asn1Decoder.class );
     
     /** A speedup for logger */
-    private static final boolean IS_DEBUG = log.isDebugEnabled();
+    private static final boolean IS_DEBUG = LOG.isDebugEnabled();
     
     /** This flag is used to indicate that there are more bytes in the stream */
     private static final boolean MORE = true;
@@ -120,7 +120,7 @@
             if ( IS_DEBUG )
             {
                 byte tag = container.getCurrentTLV().getTag();
-                log.debug( "Tag {} has been decoded", Asn1StringUtils.dumpByte( tag ) );
+                LOG.debug( "Tag {} has been decoded", Asn1StringUtils.dumpByte( tag ) );
             }
 
             return MORE;
@@ -157,7 +157,7 @@
 
         if ( IS_DEBUG ) 
         {
-            log.debug( "TLV Tree : {}", sb.toString() );
+            LOG.debug( "TLV Tree : {}", sb.toString() );
         }
     }
 
@@ -232,7 +232,7 @@
 
                 if ( expectedLength > 4 )
                 {
-                    log.error( "Overflow : can't have more than 4 bytes long length" );
+                    LOG.error( "Overflow : can't have more than 4 bytes long length" );
                     throw new DecoderException( "Overflow : can't have more than 4 bytes
long length" );
                 }
 
@@ -243,7 +243,7 @@
             }
             else
             {
-                log.error( "Length reserved extension used" );
+                LOG.error( "Length reserved extension used" );
                 throw new DecoderException( "Length reserved extension used" );
             }
 
@@ -282,7 +282,7 @@
 
                 if ( IS_DEBUG )
                 {
-                    log.debug( "  current byte : {}", Asn1StringUtils.dumpByte( octet ) );
+                    LOG.debug( "  current byte : {}", Asn1StringUtils.dumpByte( octet ) );
                 }
 
                 tlv.incLengthBytesRead();
@@ -362,7 +362,7 @@
         
         if ( tlv == null )
         {
-            log.error( "The current container TLV is null." );
+            LOG.error( "The current container TLV is null." );
             throw new DecoderException( "Current TLV is null" );
         }
         
@@ -375,7 +375,7 @@
 
         if ( IS_DEBUG )
         {
-            log.debug( "Parent length : {}", getParentLength( parentTLV ) );
+            LOG.debug( "Parent length : {}", getParentLength( parentTLV ) );
         }
 
         if ( parentTLV == null )
@@ -387,7 +387,7 @@
 
             if ( IS_DEBUG )
             {
-                log.debug( "Root TLV[{}]", Integer.valueOf( length ) );
+                LOG.debug( "Root TLV[{}]", Integer.valueOf( length ) );
             }
         }
         else
@@ -401,7 +401,7 @@
             {
                 // The expected length is lower than the Value length of the
                 // current TLV. This is an error...
-                log.error( "tlv[{}, {}]", Integer.valueOf( expectedLength ), Integer.valueOf(
currentLength ) );
+                LOG.error( "tlv[{}, {}]", Integer.valueOf( expectedLength ), Integer.valueOf(
currentLength ) );
                 throw new DecoderException( "The current Value length is above the expected
length" );
             }
 
@@ -494,7 +494,7 @@
 
         if ( IS_DEBUG )
         {
-            log.debug( "Length {} has been decoded", Integer.valueOf( length ) );
+            LOG.debug( "Length {} has been decoded", Integer.valueOf( length ) );
         }
 
         if ( length == 0 )
@@ -636,7 +636,7 @@
                 }
                 else
                 {
-                    log.error( "The PDU is decoded, but we should have had more TLVs" );
+                    LOG.error( "The PDU is decoded, but we should have had more TLVs" );
                     throw new DecoderException( "Truncated PDU. Some elements are lacking,
accordingly to the grammar" );
                 }
             }
@@ -724,12 +724,23 @@
          */
 
         boolean hasRemaining = stream.hasRemaining();
+        
+        // Increment the PDU size counter.
+        container.incrementDecodeBytes( stream.remaining() );
+        
+        if ( container.getDecodeBytes() > container.getMaxPDUSize() )
+        {
+            String message = "The PDU current size (" + container.getDecodeBytes() +
+            ") exceeds the maximum allowed PDU size (" + container.getMaxPDUSize() +")";
+            LOG.error( message );
+            throw new DecoderException( message );
+        }
 
         if ( IS_DEBUG )
         {
-            log.debug( ">>>==========================================" );
-            log.debug( "--> Decoding a PDU" );
-            log.debug( ">>>------------------------------------------" );
+            LOG.debug( ">>>==========================================" );
+            LOG.debug( "--> Decoding a PDU" );
+            LOG.debug( ">>>------------------------------------------" );
         }
 
         while ( hasRemaining )
@@ -737,17 +748,17 @@
 
             if ( IS_DEBUG )
             {
-                log.debug( "--- State = {} ---", stateToString( container.getState() ) );
+                LOG.debug( "--- State = {} ---", stateToString( container.getState() ) );
 
                 if ( stream.hasRemaining() )
                 {
                     byte octet = stream.get( stream.position() );
 
-                    log.debug( "  current byte : {}", Asn1StringUtils.dumpByte( octet ) );
+                    LOG.debug( "  current byte : {}", Asn1StringUtils.dumpByte( octet ) );
                 }
                 else
                 {
-                    log.debug( "  no more byte to decode in the stream" );
+                    LOG.debug( "  no more byte to decode in the stream" );
                 }
             }
 
@@ -800,7 +811,7 @@
                 case TLVStateEnum.PDU_DECODED:
                     // We have to deal with the case where there are
                     // more bytes in the buffer, but the PDU has been decoded.
-                    log.warn( "The PDU has been fully decoded but there are still bytes in
the buffer." );
+                    LOG.warn( "The PDU has been fully decoded but there are still bytes in
the buffer." );
 
                     hasRemaining = false;
 
@@ -813,32 +824,32 @@
 
         if ( IS_DEBUG )
         {
-            log.debug( "<<<------------------------------------------" );
+            LOG.debug( "<<<------------------------------------------" );
 
             if ( container.getState() == TLVStateEnum.PDU_DECODED )
             {
                 if ( container.getCurrentTLV() != null )
                 {
-                    log.debug( "<-- Stop decoding : {}", container.getCurrentTLV().toString()
);
+                    LOG.debug( "<-- Stop decoding : {}", container.getCurrentTLV().toString()
);
                 }
                 else
                 {
-                    log.debug( "<-- Stop decoding : null current TLV" );
+                    LOG.debug( "<-- Stop decoding : null current TLV" );
                 }
             }
             else
             {
                 if ( container.getCurrentTLV() != null )
                 {
-                    log.debug( "<-- End decoding : {}", container.getCurrentTLV().toString()
);
+                    LOG.debug( "<-- End decoding : {}", container.getCurrentTLV().toString()
);
                 }
                 else
                 {
-                    log.debug( "<-- End decoding : null current TLV" );
+                    LOG.debug( "<-- End decoding : null current TLV" );
                 }
             }
 
-            log.debug( "<<<==========================================" );
+            LOG.debug( "<<<==========================================" );
         }
 
         return;

Modified: directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/IAsn1Container.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/IAsn1Container.java?rev=722296&r1=722295&r2=722296&view=diff
==============================================================================
--- directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/IAsn1Container.java
(original)
+++ directory/shared/branches/shared-mina2/asn1/src/main/java/org/apache/directory/shared/asn1/ber/IAsn1Container.java
Mon Dec  1 15:59:32 2008
@@ -139,4 +139,33 @@
      * @return a unique value representing the current TLV id
      */
     int getTlvId();
+    
+    
+    /**
+     * @return The number of decoded bytes for this message. This is used
+     * to control the PDU size and avoid PDU exceeding the maximum allowed
+     * size to break the server.
+     */
+    int getDecodeBytes();
+
+    
+    /**
+     * Increment the decodedBytes by the latest received buffer's size.
+     * @param nb The buffer size.
+     */
+    void incrementDecodeBytes( int nb );
+
+
+    /**
+     * @return The maximum PDU size.
+     */
+    int getMaxPDUSize();
+    
+    
+    /**
+     * Set the maximum PDU size.
+     * @param maxPDUSize The maximum PDU size (if negative or null, will be
+     * replaced by the max integer value)
+     */
+    void setMaxPDUSize( int maxPDUSize );
 }

Modified: directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapMessageContainer.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapMessageContainer.java?rev=722296&r1=722295&r2=722296&view=diff
==============================================================================
--- directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapMessageContainer.java
(original)
+++ directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/LdapMessageContainer.java
Mon Dec  1 15:59:32 2008
@@ -114,6 +114,7 @@
         ldapMessage = null;
         messageId = 0;
         currentControl = null;
+        decodeBytes = 0;
     }
 
 

Modified: directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixDecoder.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixDecoder.java?rev=722296&r1=722295&r2=722296&view=diff
==============================================================================
--- directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixDecoder.java
(original)
+++ directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixDecoder.java
Mon Dec  1 15:59:32 2008
@@ -69,12 +69,15 @@
      * 
      * @param provider the owning provider.
      * @param binaryAttributeDetector checks for binary attributes 
+     * @param maxPDUSize the maximum size a PDU can be
      */
-    public TwixDecoder( Provider provider, BinaryAttributeDetector binaryAttributeDetector
)
+    public TwixDecoder( Provider provider, BinaryAttributeDetector binaryAttributeDetector,
int maxPDUSize )
     {
         this.provider = provider;
-        this.ldapMessageContainer = new LdapMessageContainer( binaryAttributeDetector );
-        this.ldapDecoder = new LdapDecoder();
+        ldapMessageContainer = new LdapMessageContainer( binaryAttributeDetector );
+        ldapDecoder = new LdapDecoder();
+        
+        ldapMessageContainer.setMaxPDUSize( maxPDUSize );
     }
 
 

Modified: directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixProvider.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixProvider.java?rev=722296&r1=722295&r2=722296&view=diff
==============================================================================
--- directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixProvider.java
(original)
+++ directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/codec/TwixProvider.java
Mon Dec  1 15:59:32 2008
@@ -85,8 +85,8 @@
      * @throws org.apache.directory.shared.ldap.message.spi.ProviderException
      *             if the provider or its decoder cannot be found
      */
-    public ProviderDecoder getDecoder( BinaryAttributeDetector binaryAttributeDetector )
throws ProviderException
+    public ProviderDecoder getDecoder( BinaryAttributeDetector binaryAttributeDetector, int
maxPDUSize ) throws ProviderException
     {
-        return new TwixDecoder( this, binaryAttributeDetector );
+        return new TwixDecoder( this, binaryAttributeDetector, maxPDUSize );
     }
 }

Modified: directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/message/MessageDecoder.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/message/MessageDecoder.java?rev=722296&r1=722295&r2=722296&view=diff
==============================================================================
--- directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/message/MessageDecoder.java
(original)
+++ directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/message/MessageDecoder.java
Mon Dec  1 15:59:32 2008
@@ -63,11 +63,25 @@
      */
     public MessageDecoder( BinaryAttributeDetector binaryAttributeDetector ) throws MessageException
     {
+        this( binaryAttributeDetector, Integer.MAX_VALUE );
+    }
+    
+    
+    /**
+     * Creates a MessageDecoder using default properties for enabling a BER
+     * library provider.
+     * 
+     * @param binaryAttributeDetector detects whether or not an attribute is binary
+     * @param maxPDUSize the maximum size a PDU can be
+     * @throws MessageException if there is a problem creating this decoder.
+     */
+    public MessageDecoder( BinaryAttributeDetector binaryAttributeDetector, int maxPDUSize
) throws MessageException
+    {
         // We need to get the encoder class name
         Hashtable<Object, Object> providerEnv = Provider.getEnvironment();
         
         this.provider = Provider.getProvider( providerEnv );
-        this.decoder = this.provider.getDecoder( binaryAttributeDetector );
+        this.decoder = this.provider.getDecoder( binaryAttributeDetector, maxPDUSize );
         this.decoder.setCallback( new DecoderCallback()
         {
             public void decodeOccurred( StatefulDecoder decoder, Object decoded )

Modified: directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/message/spi/Provider.java
URL: http://svn.apache.org/viewvc/directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/message/spi/Provider.java?rev=722296&r1=722295&r2=722296&view=diff
==============================================================================
--- directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/message/spi/Provider.java
(original)
+++ directory/shared/branches/shared-mina2/ldap/src/main/java/org/apache/directory/shared/ldap/message/spi/Provider.java
Mon Dec  1 15:59:32 2008
@@ -176,8 +176,10 @@
      * @return the provider's decoder.
      * @throws ProviderException if the provider or its decoder cannot be found
      * @param binaryAttributeDetector detects whether or not attributes are binary
+     * @param maxPDUSize the maximum size a PDU can be
      */
-    public abstract ProviderDecoder getDecoder( BinaryAttributeDetector binaryAttributeDetector
)
+    public abstract ProviderDecoder getDecoder( BinaryAttributeDetector binaryAttributeDetector,
+        int maxPDUSize )
             throws ProviderException;
 
 



Mime
View raw message