]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
ITS#9045 Do not share cn=config entries with outside code
authorOndřej Kuzník <ondra@mistotebe.net>
Wed, 26 Oct 2022 14:55:18 +0000 (15:55 +0100)
committerQuanah Gibson-Mount <quanah@openldap.org>
Mon, 31 Oct 2022 18:16:42 +0000 (18:16 +0000)
config_back_entry_get currently returns the entry directly without
securing the rwlock, which is unsafe. However we can't keep holding it
on return in case the caller decides to hold onto the entry
indefinitely, hence rlock+entry_dup+runlock.

servers/slapd/bconfig.c

index 8ee57bea1b9cb62418f93cd59aa6ac5a6a986912..dda41a5bfa5dd5d9e6df12ac33a0f5d8516cd6c9 100644 (file)
@@ -6862,7 +6862,6 @@ out:
        return rs->sr_err;
 }
 
-/* no-op, we never free entries */
 int config_entry_release(
        Operation *op,
        Entry *e,
@@ -6882,6 +6881,8 @@ int config_entry_release(
                } else {
                        entry_free( e );
                }
+       } else {
+               entry_free( e );
        }
        return rc;
 }
@@ -6898,21 +6899,31 @@ int config_back_entry_get(
 {
        CfBackInfo *cfb;
        CfEntryInfo *ce, *last;
-       int rc = LDAP_NO_SUCH_OBJECT;
+       Entry *e = NULL;
+       int locked = 0, rc = LDAP_NO_SUCH_OBJECT;
 
        cfb = (CfBackInfo *)op->o_bd->be_private;
 
+       if ( !ldap_pvt_thread_pool_pausequery( &connection_pool ) ) {
+               ldap_pvt_thread_rdwr_rlock( &cfb->cb_rwlock );
+               locked = 1;
+       }
        ce = config_find_base( cfb->cb_root, ndn, &last );
        if ( ce ) {
-               *ent = ce->ce_entry;
-               if ( *ent ) {
+               e = ce->ce_entry;
+               if ( e ) {
                        rc = LDAP_SUCCESS;
-                       if ( oc && !is_entry_objectclass_or_sub( *ent, oc ) ) {
+                       if ( oc && !is_entry_objectclass_or_sub( e, oc ) ) {
                                rc = LDAP_NO_SUCH_ATTRIBUTE;
-                               *ent = NULL;
+                               e = NULL;
                        }
                }
        }
+       if ( e ) {
+               *ent = entry_dup( e );
+       }
+       if ( locked )
+               ldap_pvt_thread_rdwr_runlock( &cfb->cb_rwlock );
 
        return rc;
 }