From a6f3106afcf4324c11e85e2043116498b00d3f38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Kuzn=C3=ADk?= Date: Wed, 26 Oct 2022 15:55:18 +0100 Subject: [PATCH] ITS#9045 Do not share cn=config entries with outside code 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 | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c index 8ee57bea1b..dda41a5bfa 100644 --- a/servers/slapd/bconfig.c +++ b/servers/slapd/bconfig.c @@ -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; }