https://bugs.openldap.org/show_bug.cgi?id=10336
Issue ID: 10336 Summary: slapd crashes with segfault in mdb_delete.c on non-existent tree part deletion Product: OpenLDAP Version: 2.6.9 Hardware: All OS: All Status: UNCONFIRMED Keywords: needs_review Severity: normal Priority: --- Component: slapd Assignee: bugs@openldap.org Reporter: A.Asemov@edpnet.com Target Milestone: ---
slapd crashes with segfault in mdb_delete.c on non-existent tree part deletion. Applies to 2.6.7, 2.6.8, 2.6.9
----------
Prerequisites:
----------
- mdb backend - empty mdb database
----------
Sample reproducer:
----------
ldapdelete -x -H ldap://127.0.0.1 -w "password" -D "cn=MyApplication,dc=Contacts,dc=MyTree" "dc=Contacts,dc=MyTree"
----------
Expected behavior:
----------
ldap_delete: No such object (32)
----------
Actual behavior:
----------
Program terminated with signal SIGSEGV, Segmentation fault. #0 0x00005566507b96e0 in mdb_delete (op=0x7f3f0c002910, rs=0x7f3f19bfd8a0) at ../../../../openldap-epel-2.6.8/openldap-2.6.8/servers/slapd/back-mdb/delete.c:151
----------
Sample slapd.conf:
----------
include /etc/openldap/schema/core.schema include /etc/openldap/schema/cosine.schema include /etc/openldap/schema/inetorgperson.schema include /etc/openldap/schema/openldap.schema
allow bind_v2
pidfile /var/run/openldap/slapd.pid argsfile /var/run/openldap/slapd.args
modulepath /usr/lib64/openldap #moduleload back_shell.la moduleload sssvlv.la moduleload valsort.la
TLSCACertificatePath /etc/openldap/certs TLSCertificateFile /etc/<path removed>.crt TLSCertificateKeyFile /etc/<path removed>.key
database mdb suffix "dc=Contacts,dc=MyTree" directory "/var/lib/ldap" checkpoint 1024 1 dbnosync maxsize 1048576000 index objectClass eq,pres index ou,cn eq,pres,sub index uidNumber,gidNumber eq,pres index uid eq,pres,sub rootdn "cn=MyApplication,dc=Contacts,dc=MyTree" rootpw "{SSHA}<removed>" access to * by dn="cn=Phone,dc=Contacts,dc=MyTree" read by peername.ip=127.0.0.1 write by anonymous auth by * none overlay sssvlv sssvlv-max 1000 sssvlv-maxperconn 1000
----------
Sample fix:
I am not versed in OpenLDAP code so I can't tell if it's semantically correct. Seems like "e" gets NULL in this piece of code and the piece of code does not verify if "e" is NULL. Adding check for ( e ) makes slapd correctly return ldap_delete: No such object (32) instead of segfaulting.
----------
--- a/servers/slapd/back-mdb/delete.c 2024-05-21 19:19:11.000000000 +0200 +++ b/servers/slapd/back-mdb/delete.c 2025-05-12 14:43:04.652396852 +0200 @@ -148,17 +148,19 @@ "<=- " LDAP_XSTRING(mdb_delete) ": no such object %s\n", op->o_req_dn.bv_val );
- rs->sr_matched = ch_strdup( e->e_dn ); - if ( is_entry_referral( e )) { - BerVarray ref = get_entry_referrals( op, e ); - rs->sr_ref = referral_rewrite( ref, &e->e_name, - &op->o_req_dn, LDAP_SCOPE_DEFAULT ); - ber_bvarray_free( ref ); - } else { - rs->sr_ref = NULL; + if ( e ) { + rs->sr_matched = ch_strdup( e->e_dn ); + if ( is_entry_referral( e )) { + BerVarray ref = get_entry_referrals( op, e ); + rs->sr_ref = referral_rewrite( ref, &e->e_name, + &op->o_req_dn, LDAP_SCOPE_DEFAULT ); + ber_bvarray_free( ref ); + } else { + rs->sr_ref = NULL; + } + mdb_entry_return( op, e ); + e = NULL; } - mdb_entry_return( op, e ); - e = NULL;
rs->sr_err = LDAP_REFERRAL; rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;