Issue 8107 - olcMemberOfDangling: error doesn't prevent adding nonexistent member to group
Summary: olcMemberOfDangling: error doesn't prevent adding nonexistent member to group
Status: VERIFIED FIXED
Alias: None
Product: OpenLDAP
Classification: Unclassified
Component: slapd (show other issues)
Version: unspecified
Hardware: All All
: --- normal
Target Milestone: ---
Assignee: OpenLDAP project
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-04-17 19:25 UTC by Ryan Tandy
Modified: 2015-07-02 17:50 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Ryan Tandy 2015-04-17 19:25:52 UTC
Full_Name: Ryan Tandy
Version: RE24
OS: Ubuntu
URL: 
Submission from: (NULL) (142.31.146.2)


$ git describe
OPENLDAP_REL_ENG_2_4_40-208-gfd03ec0
$ ./configure --disable-bdb --disable-hdb --enable-memberof && make -j8 && sudo
make STRIP= install
[...]
$ slapadd -Fconfig.d -n0
dn: cn=config
objectClass%3ololcGlobal

dn: cn=schema,cn=config
objectClass: olcSchemaConfig

include: file:///usr/local/etc/openldap/schema/core.ldif
include: file:///usr/local/etc/openldap/schema/cosine.ldif

dn: olcDatabase={1}mdb,cn=config
objectClass: olcMdbConfig
olcDbDirectory: data.d
olcSuffix: dc=example,dc=com
olcDbIndex: objectClass eq
olcAccess: to * by dn="cn=admin,dc=example,dc=com" write by * read

dn: olcOverlay=memberof,olcDatabase={1}mdb,cn=config
objectClass: olcMemberOf
olcMemberOfDangling: error

$ slapadd -Fconfig.d
dn: dc=example,dc=com
objectClass: domain

dn: cn=admin,dc=example,dc=com
objectClass: organizationalRole
objectClass: simpleSecurityObject
userPassword: secret

$ /usr/local/libexec/slapd -h ldap://:9000 -Fnfigig.d
$ ldapadd -H ldap://:9000 -x -D cn=admin,dc=example,dc=com -w secret
dn: cn=testgroup,dc=example,dc=com
objectClass: groupOfNames
member: cn=nonexistent

adding new entry "cn=testgroup,dc=example,dc=com"
ldap_add: Constraint violation (19)
	additional info: adding non-existing object as group member

$ ldapsearch -H ldap://:9000 -x -b cn=testgroup,dc=example,dc=com
# extended LDIF
#
# LDAPv3
# base <cn=testgroup,dc=example,dc=com> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
%%2#

# search result
search: 2
result: 32 No such object
matchedDN: dc=example,dc=com

# numResponses: 1

OK, that's fine. The new entry was rejected.

$ ldapadd -H ldap://:9000 -x -D cn=admin,dc=example,dc=com -w secret
dn: cn=testgroup,dc=example,dc=com
objectClass: groupOfNames
member: cn=admin,dc=example,dc=com

adding new entry "cn=testgroup,dc=example,dc=com"

dn: cn=testgroup,dc=example,dc=com
changetype: modify
add: member
member: cn=nonexistent

modifying entry "cn=testgroup,dc=example,dc=com"
ldap_modify: Constraint violation (19)
	additional info: adding non-existing object as group member

$ ldapsearch -H ldap://:9000 -x -b cn=testgroup,dc=example,dc=com
# extended LDIF
#
# LDAPv3
# base <cn=testgroup,dc=example,dc=com> with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# testgroup, example.com
dn: cn=testgroup,dc=example,dc=com
objectClass: groupOfNames
member: cn=admin,dc=example,dc=com
member: cn=nonexistent
cn: testgroup

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

This is unexpected. The member addition was rejected, but somehow the
modification went through anyway?

Seems like something spooky is going on here...

903						9%9	send_ldap_result( op, rs );
(gdb) p rc
$4 = 19
(gdb) n
55315ce0 send_ldap_result: conn=1001 op=2 p=3
55315ce0 send_ldap_response: msgid=3 tag=103 err=19
ber_flush2: 56 bytes to sd 12
1214		op->o_dn = save_dn;
(gdb) p rc
$5 = 32768
(gdb) p rs->sr_err
$6 = 19D%D

Am I reading that right, send_ldap_result is somehow overwriting rc in the
caller? Happens at -O0 as well as -O2.
Comment 1 Ryan Tandy 2015-04-18 22:47:47 UTC
Adding a new group containing a nonexistent member, or or a nonexistent 
member to an existing group, triggers the following AddressSanitizer 
splat. No error when adding a valid member, or with memberof disabled.

(Line numbers from git master)

5532dc8c connection_get(11): got connid=1000
5532dc8c connection_read(11): checking for input on id=1000
ber_get_next
ber_get_next: tag 0x30 len 66 contents:
5532dc8c op tag 0x66, time 1429396620
ber_get_next
5532dc8c conn=1000 op=2 do_modify
ber_scanf fmt ({m) ber:
ber_scanf fmt ({e{m[W]}}) ber:
5532dc8c >>> dnPrettyNormal: <cn=testgroup,dc=example,dc=com>
5532dc8c <<< dnPrettyNormal: <cn=testgroup,dc=example,dc=com>, <cn=testgroup,dc=example,dc=com>
5532dc8c >>> dnPretty: <cn=dummy>
5532dc8c <<< dnPretty: <cn=dummy>
5532dc8c >>> dnNormalize: <cn=dummy>
5532dc8c <<< dnNormalize: <cn=dummy>
5532dc8c => mdb_search
5532dc8c mdb_dn2entry("cn=testgroup,dc=example,dc=com")
5532dc8c => mdb_dn2id("cn=testgroup,dc=example,dc=com")
5532dc8c <= mdb_dn2id: got id=0x3
5532dc8c => mdb_entry_decode:
5532dc8c <= mdb_entry_decode
5532dc8c send_ldap_result: conn=1000 op=2 p=3
5532dc8c mdb_dn2entry("cn=dummy")
5532dc8c => mdb_dn2id("cn=dummy")
=================================================================
==1998==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000024967 at pc 0x000000ebdb1f bp 0x7f91f2773650 sp 0x7f91f2773648
READ of size 1 at 0x602000024967 thread T2
    #0 0xebdb1e in lutil_strncopy /home/ryan/pkg/openldap/openldap/libraries/liblutil/utils.c:317:2
    #1 0xd10adb in mdb_dn2id /home/ryan/pkg/openldap/openldap/servers/slapd/back-mdb/dn2id.c:360:9
    #2 0xd0798e in mdb_dn2entry /home/ryan/pkg/openldap/openldap/servers/slapd/back-mdb/dn2entry.c:51:7
    #3 0xd4afb5 in mdb_entry_get /home/ryan/pkg/openldap/openldap/servers/slapd/back-mdb/id2entry.c:336:7
    #4 0xa8feb5 in overlay_entry_get_ov /home/ryan/pkg/openldap/openldap/servers/slapd/backover.c:376:9
    #5 0xaa6dd2 in over_entry_get_rw /home/ryan/pkg/openldap/openldap/servers/slapd/backover.c:408:9
    #6 0x6a4d9c in be_entry_get_rw /home/ryan/pkg/openldap/openldap/servers/slapd/backend.c:1436:10
    #7 0xdb6298 in memberof_op_modify /home/ryan/pkg/openldap/openldap/servers/slapd/overlays/memberof.c:892:12
    #8 0xa931bb in overlay_op_walk /home/ryan/pkg/openldap/openldap/servers/slapd/backover.c:681:9
    #9 0xaadbea in over_op_func /home/ryan/pkg/openldap/openldap/servers/slapd/backover.c:749:7
    #10 0xaa5493 in over_op_modify /home/ryan/pkg/openldap/openldap/servers/slapd/backover.c:788:9
    #11 0x7144f2 in fe_op_modify /home/ryan/pkg/openldap/openldap/servers/slapd/modify.c:303:4
    #12 0x70b08e in do_modify /home/ryan/pkg/openldap/openldap/servers/slapd/modify.c:177:15
    #13 0x609ccc in connection_operation /home/ryan/pkg/openldap/openldap/servers/slapd/connection.c:1134:7
    #14 0x602ec3 in connection_read_thread /home/ryan/pkg/openldap/openldap/servers/slapd/connection.c:1280:14
    #15 0xf094de in ldap_int_thread_pool_wrapper /home/ryan/pkg/openldap/openldap/libraries/libldap_r/tpool.c:958:3
    #16 0x7f91fc2f40a3 in start_thread /build/glibc-Ir_s5K/glibc-2.19/nptl/pthread_create.c:309
    #17 0x7f91fb70604c in clone /build/glibc-Ir_s5K/glibc-2.19/misc/../sysdeps/unix/sysv/linux/x86_64/clone.S:111

0x602000024967 is located 9 bytes to the left of 10-byte region [0x602000024970,0x60200002497a)
allocated by thread T2 here:
    #0 0x4bb46b in malloc (/usr/local/libexec/slapd+0x4bb46b)
    #1 0x10e4d7f in ber_memalloc_x /home/ryan/pkg/openldap/openldap/libraries/liblber/memory.c:228:9
    #2 0xfc01e1 in ldap_dn2bv_x /home/ryan/pkg/openldap/openldap/libraries/libldap_r/getdn.c:3015:23
    #3 0x6e7a37 in dnNormalize /home/ryan/pkg/openldap/openldap/servers/slapd/dn.c:454:8
    #4 0x744d1d in ordered_value_normalize /home/ryan/pkg/openldap/openldap/servers/slapd/value.c:587:7
    #5 0x7106cd in slap_mods_check /home/ryan/pkg/openldap/openldap/servers/slapd/modify.c:627:11
    #6 0x70aca3 in do_modify /home/ryan/pkg/openldap/openldap/servers/slapd/modify.c:168:15
    #7 0x609ccc in connection_operation /home/ryan/pkg/openldap/openldap/servers/slapd/connection.c:1134:7
    #8 0x602ec3 in connection_read_thread /home/ryan/pkg/openldap/openldap/servers/slapd/connection.c:1280:14
    #9 0xf094de in ldap_int_thread_pool_wrapper /home/ryan/pkg/openldap/openldap/libraries/libldap_r/tpool.c:958:3
    #10 0x7f91fc2f40a3 in start_thread /build/glibc-Ir_s5K/glibc-2.19/nptl/pthread_create.c:309

Thread T2 created by T1 here:
    #0 0x4a309f in __interceptor_pthread_create (/usr/local/libexec/slapd+0x4a309f)
    #1 0xf1d269 in ldap_pvt_thread_create /home/ryan/pkg/openldap/openldap/libraries/libldap_r/thr_posix.c:165:8
    #2 0xf05f35 in ldap_pvt_thread_pool_submit /home/ryan/pkg/openldap/openldap/libraries/libldap_r/tpool.c:420:12
    #3 0x5e92a5 in slap_listener_activate /home/ryan/pkg/openldap/openldap/servers/slapd/daemon.c:2097:7
    #4 0x5e17a4 in slapd_daemon_task /home/ryan/pkg/openldap/openldap/servers/slapd/daemon.c:2728:10
    #5 0x7f91fc2f40a3 in start_thread /build/glibc-Ir_s5K/glibc-2.19/nptl/pthread_create.c:309

Thread T1 created by T0 here:
    #0 0x4a309f in __interceptor_pthread_create (/usr/local/libexec/slapd+0x4a309f)
    #1 0xf1d269 in ldap_pvt_thread_create /home/ryan/pkg/openldap/openldap/libraries/libldap_r/thr_posix.c:165:8
    #2 0x5d2539 in slapd_daemon /home/ryan/pkg/openldap/openldap/servers/slapd/daemon.c:2898:8
    #3 0x4e2e3e in main /home/ryan/pkg/openldap/openldap/servers/slapd/main.c:1018:7
    #4 0x7f91fb641b44 in __libc_start_main /build/glibc-Ir_s5K/glibc-2.19/csu/libc-start.c:287

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/ryan/pkg/openldap/openldap/libraries/liblutil/utils.c:317 lutil_strncopy
Shadow bytes around the buggy address:
  0x0c047fffc8d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fffc8e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fffc8f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fffc900: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fffc910: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c047fffc920: fa fa fa fa fa fa fa fa fa fa fa fa[fa]fa 00 02
  0x0c047fffc930: fa fa fd fd fa fa fd fd fa fa fd fa fa fa 00 02
  0x0c047fffc940: fa fa fd fd fa fa fd fa fa fa fd fd fa fa fd fd
  0x0c047fffc950: fa fa fd fa fa fa fd fd fa fa fd fa fa fa fd fa
  0x0c047fffc960: fa fa fd fd fa fa fd fa fa fa fd fa fa fa fd fa
  0x0c047fffc970: fa fa fd fa fa fa fd fa fa fa fd fd fa fa fd fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  ASan internal:           fe
==1998==ABORTING

Comment 2 Ryan Tandy 2015-04-23 02:50:28 UTC
On Sat, Apr 18, 2015 at 10:47:57PM +0000, ryan@nardis.ca wrote:
>Adding a new group containing a nonexistent member, or or a nonexistent
>member to an existing group, triggers the following AddressSanitizer
>splat. No error when adding a valid member, or with memberof disabled.

That part turned out to be my fault, actually:

>    #0 0xebdb1e in lutil_strncopy /home/ryan/pkg/openldap/openldap/libraries/liblutil/utils.c:317:2
>    #1 0xd10adb in mdb_dn2id /home/ryan/pkg/openldap/openldap/servers/slapd/back-mdb/dn2id.c:360:9

The nonexistent entry I was trying to add was outside the db suffix. 
Therefore nrlen in mdb_dn2id was wrong (in my specific case, negative) 
and things got worse from there.

Testing with a nonexistent entry under the correct suffix, there are no 
complaints from AddressSanitizer.

The buggy behaviour is still present, however: the member value is added 
despite returning a 'constraint violation' result.

Comment 4 Howard Chu 2015-04-23 04:19:46 UTC
changed notes
changed state Open to Test
moved from Incoming to Software Bugs
Comment 5 Quanah Gibson-Mount 2015-04-23 17:52:07 UTC
changed notes
changed state Test to Release
Comment 6 Quanah Gibson-Mount 2015-04-23 17:54:42 UTC
changed notes
Comment 7 OpenLDAP project 2015-07-02 17:50:33 UTC
fixed in master
fixed in RE25
fixed in RE24
Comment 8 Quanah Gibson-Mount 2015-07-02 17:50:33 UTC
changed notes
changed state Release to Closed