]> git.sur5r.net Git - openldap/commitdiff
Import -llber hardening
authorKurt Zeilenga <kurt@openldap.org>
Sun, 6 May 2001 21:53:57 +0000 (21:53 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Sun, 6 May 2001 21:53:57 +0000 (21:53 +0000)
libraries/liblber/decode.c
libraries/liblber/io.c
libraries/liblber/lber-int.h
libraries/liblber/sockbuf.c

index 68463774248b921cc5939bbf85acea0c4d45ec39..d2fbcdd357176865399775363121f520cc54e5d7 100644 (file)
@@ -137,6 +137,11 @@ ber_skip_tag( BerElement *ber, ber_len_t *len )
                *len = lc;
        }
 
+       /* BER element should have enough data left */
+       if( *len > ber_pvt_ber_remaining( ber ) ) {
+               return LBER_DEFAULT;
+       }
+
        return tag;
 }
 
@@ -252,7 +257,9 @@ ber_get_stringb(
        if ( (tag = ber_skip_tag( ber, &datalen )) == LBER_DEFAULT ) {
                return LBER_DEFAULT;
        }
-       if ( datalen > (*len - 1) ) {
+
+       /* must fit within allocated space with termination */
+       if ( datalen >= *len ) {
                return LBER_DEFAULT;
        }
 
index 1e78515c4c9b3ac5a7add9d5a50f7044428b4aa3..b04edb7890e468a8c36db002994ac448f45e1aea 100644 (file)
@@ -77,7 +77,7 @@ ber_read(
 
        assert( BER_VALID( ber ) );
 
-       nleft = ber->ber_end - ber->ber_ptr;
+       nleft = ber_pvt_ber_remaining( ber );
        actuallen = nleft < len ? nleft : len;
 
        AC_MEMCPY( buf, ber->ber_ptr, actuallen );
@@ -524,15 +524,25 @@ get_lenbyte:
                ber->ber_rwptr += res;
 
                /* convert length. */
-               ber->ber_len = 0;
                for( to_go = 0; to_go < res ; to_go++ ) {
                        ber->ber_len <<= 8;
                        ber->ber_len |= netlen[to_go];
                }
+               if (PTR_IN_VAR(ber->ber_rwptr, ber->ber_len))
+                       return LBER_DEFAULT;
        }
 
 fill_buffer:   
        /* now fill the buffer. */
+
+       /* make sure length is reasonable */
+       if ( ber->ber_len == 0 ||
+               ( sb->sb_max_incoming && ber->ber_len > sb->sb_max_incoming ))
+       {
+               errno = ERANGE;
+               return LBER_DEFAULT;
+       }
+
        if (ber->ber_buf==NULL) {
                ber->ber_buf = (char *) LBER_MALLOC( ber->ber_len );
                if (ber->ber_buf==NULL) {
index 00a8f06a6caf0d98e03b2efc5bf7eddcb90f903c..ef34dfeb7d10427c50745b2398bb31df4e1d632f 100644 (file)
@@ -74,6 +74,7 @@ struct sockbuf {
        ber_socket_t            sb_fd;
        unsigned int            sb_trans_needs_read:1;
        unsigned int            sb_trans_needs_write:1;
+       ber_len_t                       sb_max_incoming;
 };
 
 #define SOCKBUF_VALID( sb )    ( (sb)->sb_valid == LBER_VALID_SOCKBUF )
index 07627ba85c633fe24ededadabd63c8353c6cc0a2..bb3eb64c74ae8bc5cd40aa100aee0692615d5a17 100644 (file)
 #include <io.h>
 #endif /* HAVE_IO_H */
 
+#if defined( HAVE_FCNTL_H )
+#include <fcntl.h>
+#endif
+
 #if defined( HAVE_SYS_FILIO_H )
 #include <sys/filio.h>
 #elif defined( HAVE_SYS_IOCTL_H )
@@ -69,6 +73,7 @@ ber_sockbuf_ctrl( Sockbuf *sb, int opt, void *arg )
        int                     ret = 0;
 
        assert( sb != NULL );
+       assert( SOCKBUF_VALID( sb ) );
 
        switch ( opt ) {
                case LBER_SB_OPT_HAS_IO:
@@ -120,6 +125,18 @@ ber_sockbuf_ctrl( Sockbuf *sb, int opt, void *arg )
                        ret = ( sb->sb_trans_needs_write ? 1 : 0 );
                        break;
 
+               case LBER_SB_OPT_GET_MAX_INCOMING:
+                       if ( arg != NULL ) {
+                               *((ber_len_t *)arg) = sb->sb_max_incoming;
+                       }
+                       ret = 1;
+                       break;
+
+               case LBER_SB_OPT_SET_MAX_INCOMING:
+                       sb->sb_max_incoming = *((ber_len_t *)arg);
+                       ret = 1;
+                       break;
+
                default:
                        ret = sb->sb_iod->sbiod_io->sbi_ctrl( sb->sb_iod,
                                opt, arg );