mirror of
https://git.centos.org/rpms/389-ds-base.git
synced 2025-02-24 00:32:54 +00:00
import 389-ds-base-1.3.6.1-26.el7_4
This commit is contained in:
parent
b69e4737bd
commit
a6639136ef
5 changed files with 724 additions and 1 deletions
|
@ -0,0 +1,58 @@
|
|||
From 72f541fd317321fbd0395dcaa77830aa8b5d35b6 Mon Sep 17 00:00:00 2001
|
||||
From: Thierry Bordaz <tbordaz@redhat.com>
|
||||
Date: Wed, 15 Nov 2017 16:38:28 +0100
|
||||
Subject: [PATCH] Ticket 49410 - opened connection can remain no longer poll,
|
||||
like hanging
|
||||
|
||||
Bug Description:
|
||||
Some opened connection are no longer poll.
|
||||
Those connections has 'gettingber' toggle set although there is
|
||||
no more worker thread reading it.
|
||||
The reason they have gettingber set is that the last
|
||||
operation had 'persistent search' flag. With such flag
|
||||
gettingber is not reset.
|
||||
persistent flag is set even when no persistent search/sync_repl
|
||||
was received on the connection.
|
||||
The problem is that the flag is tested on the wrong operation.
|
||||
The tested operation can be
|
||||
- the first operation when the connection entered in turbo mode
|
||||
- the previous operation if several ops PDUs were read on the network
|
||||
- accessing random memory
|
||||
|
||||
In theory testing the flag can lead to sigsev even
|
||||
if it never crash
|
||||
|
||||
Fix Description:
|
||||
The fix is to use the operation that is in the pblock
|
||||
In such case pb_op is no longer used, so we can get rid of it.
|
||||
In addition make pb_conn a local variable where it is used
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49410
|
||||
|
||||
Reviewed by: Ludwig Krispenz, Mark Reynolds
|
||||
|
||||
Platforms tested: F26
|
||||
|
||||
Flag Day: no
|
||||
|
||||
Doc impact: no
|
||||
---
|
||||
ldap/servers/slapd/connection.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c
|
||||
index 359b59a4d..c00c88578 100644
|
||||
--- a/ldap/servers/slapd/connection.c
|
||||
+++ b/ldap/servers/slapd/connection.c
|
||||
@@ -1540,6 +1540,8 @@ connection_threadmain()
|
||||
}
|
||||
|
||||
if (!thread_turbo_flag && !more_data) {
|
||||
+ Connection *pb_conn = NULL;
|
||||
+
|
||||
/* If more data is left from the previous connection_read_operation,
|
||||
we should finish the op now. Client might be thinking it's
|
||||
done sending the request and wait for the response forever.
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -0,0 +1,237 @@
|
|||
From b0d593b001d4ef1fb19348335fb39bd45b31764c Mon Sep 17 00:00:00 2001
|
||||
From: Ludwig Krispenz <lkrispen@redhat.com>
|
||||
Date: Fri, 8 Dec 2017 14:26:06 +0100
|
||||
Subject: [PATCH] Ticket 48118 - backport - changelog can be erronously rebuilt
|
||||
at startup
|
||||
|
||||
---
|
||||
ldap/servers/plugins/replication/cl5_api.c | 39 ++++++++++++++++++++++
|
||||
ldap/servers/plugins/replication/repl5.h | 1 -
|
||||
ldap/servers/plugins/replication/repl5_replica.c | 39 ++--------------------
|
||||
.../plugins/replication/repl5_replica_config.c | 2 --
|
||||
4 files changed, 41 insertions(+), 40 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/replication/cl5_api.c b/ldap/servers/plugins/replication/cl5_api.c
|
||||
index 5c2233f82..1ce8d081f 100644
|
||||
--- a/ldap/servers/plugins/replication/cl5_api.c
|
||||
+++ b/ldap/servers/plugins/replication/cl5_api.c
|
||||
@@ -304,6 +304,8 @@ static void _cl5ReadBerval (struct berval *bv, char** buff);
|
||||
static void _cl5WriteBerval (struct berval *bv, char** buff);
|
||||
static int _cl5ReadBervals (struct berval ***bv, char** buff, unsigned int size);
|
||||
static int _cl5WriteBervals (struct berval **bv, char** buff, u_int32_t *size);
|
||||
+static int32_t _cl5CheckMaxRUV(CL5DBFile *file, RUV *maxruv);
|
||||
+static int32_t _cl5CheckCSNinCL(const ruv_enum_data *element, void *arg);
|
||||
|
||||
/* replay iteration */
|
||||
#ifdef FOR_DEBUGGING
|
||||
@@ -2885,6 +2887,36 @@ static int _cl5WriteBervals (struct berval **bv, char** buff, u_int32_t *size)
|
||||
return CL5_SUCCESS;
|
||||
}
|
||||
|
||||
+static int32_t
|
||||
+_cl5CheckCSNinCL(const ruv_enum_data *element, void *arg)
|
||||
+{
|
||||
+ CL5DBFile *file = (CL5DBFile *)arg;
|
||||
+ int rc = 0;
|
||||
+
|
||||
+ DBT key = {0}, data = {0};
|
||||
+ char csnStr[CSN_STRSIZE];
|
||||
+
|
||||
+ /* construct the key */
|
||||
+ key.data = csn_as_string(element->csn, PR_FALSE, csnStr);
|
||||
+ key.size = CSN_STRSIZE;
|
||||
+
|
||||
+ data.flags = DB_DBT_MALLOC;
|
||||
+
|
||||
+ rc = file->db->get(file->db, NULL /*txn*/, &key, &data, 0);
|
||||
+
|
||||
+ slapi_ch_free(&(data.data));
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+static int32_t
|
||||
+_cl5CheckMaxRUV(CL5DBFile *file, RUV *maxruv)
|
||||
+{
|
||||
+ int rc = 0;
|
||||
+
|
||||
+ rc = ruv_enumerate_elements(maxruv, _cl5CheckCSNinCL, (void *)file);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
/* upgrade from db33 to db41
|
||||
* 1. Run recovery on the database environment using the DB_ENV->open method
|
||||
* 2. Remove any Berkeley DB environment using the DB_ENV->remove method
|
||||
@@ -4248,6 +4280,13 @@ static int _cl5WriteRUV (CL5DBFile *file, PRBool purge)
|
||||
rc = ruv_to_bervals(file->maxRUV, &vals);
|
||||
}
|
||||
|
||||
+ if (!purge && _cl5CheckMaxRUV(file, file->maxRUV)) {
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name_cl,
|
||||
+ "_cl5WriteRUV - changelog maxRUV not found in changelog for file %s\n",
|
||||
+ file->name);
|
||||
+ return CL5_DB_ERROR;
|
||||
+ }
|
||||
+
|
||||
key.size = CSN_STRSIZE;
|
||||
|
||||
rc = _cl5WriteBervals (vals, &buff, &data.size);
|
||||
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
|
||||
index 718f64ef1..9c4789f9e 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5.h
|
||||
+++ b/ldap/servers/plugins/replication/repl5.h
|
||||
@@ -620,7 +620,6 @@ Object *replica_get_for_backend (const char *be_name);
|
||||
void replica_set_purge_delay (Replica *r, PRUint32 purge_delay);
|
||||
void replica_set_tombstone_reap_interval (Replica *r, long interval);
|
||||
void replica_update_ruv_consumer (Replica *r, RUV *supplier_ruv);
|
||||
-void replica_set_ruv_dirty (Replica *r);
|
||||
Slapi_Entry *get_in_memory_ruv(Slapi_DN *suffix_sdn);
|
||||
int replica_write_ruv (Replica *r);
|
||||
char *replica_get_dn(Replica *r);
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
|
||||
index 7927ac30a..3c7281a42 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_replica.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_replica.c
|
||||
@@ -46,7 +46,6 @@ struct replica {
|
||||
char* legacy_purl; /* partial url of the legacy supplier */
|
||||
ReplicaId repl_rid; /* replicaID */
|
||||
Object *repl_ruv; /* replica update vector */
|
||||
- PRBool repl_ruv_dirty; /* Dirty flag for ruv */
|
||||
CSNPL *min_csn_pl; /* Pending list for minimal CSN */
|
||||
void *csn_pl_reg_id; /* registration assignment for csn callbacks */
|
||||
unsigned long repl_state_flags; /* state flags */
|
||||
@@ -855,7 +854,6 @@ replica_set_ruv (Replica *r, RUV *ruv)
|
||||
}
|
||||
|
||||
r->repl_ruv = object_new((void*)ruv, (FNFree)ruv_destroy);
|
||||
- r->repl_ruv_dirty = PR_TRUE;
|
||||
|
||||
replica_unlock(r->repl_lock);
|
||||
}
|
||||
@@ -941,11 +939,6 @@ replica_update_ruv(Replica *r, const CSN *updated_csn, const char *replica_purl)
|
||||
slapi_sdn_get_dn(r->repl_root),
|
||||
csn_as_string(updated_csn, PR_FALSE, csn_str));
|
||||
}
|
||||
- else
|
||||
- {
|
||||
- /* RUV updated - mark as dirty */
|
||||
- r->repl_ruv_dirty = PR_TRUE;
|
||||
- }
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1526,8 +1519,6 @@ replica_dump(Replica *r)
|
||||
slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "\tupdate dn: %s\n",
|
||||
updatedn_list? updatedn_list : "not configured");
|
||||
slapi_ch_free_string(&updatedn_list);
|
||||
- slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "\truv: %s configured and is %sdirty\n",
|
||||
- r->repl_ruv ? "" : "not", r->repl_ruv_dirty ? "" : "not ");
|
||||
slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "\tCSN generator: %s configured\n",
|
||||
r->repl_csngen ? "" : "not");
|
||||
/* JCMREPL - Dump Referrals */
|
||||
@@ -1877,7 +1868,6 @@ int replica_check_for_data_reload (Replica *r, void *arg)
|
||||
|
||||
ruv_force_csn_update_from_ruv(upper_bound_ruv, r_ruv,
|
||||
"Force update of database RUV (from CL RUV) -> ", SLAPI_LOG_NOTICE);
|
||||
- replica_set_ruv_dirty(r);
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -2994,12 +2984,6 @@ replica_write_ruv (Replica *r)
|
||||
|
||||
replica_lock(r->repl_lock);
|
||||
|
||||
- if (!r->repl_ruv_dirty)
|
||||
- {
|
||||
- replica_unlock(r->repl_lock);
|
||||
- return rc;
|
||||
- }
|
||||
-
|
||||
PR_ASSERT (r->repl_ruv);
|
||||
|
||||
ruv_to_smod ((RUV*)object_get_data(r->repl_ruv), &smod);
|
||||
@@ -3034,19 +3018,13 @@ replica_write_ruv (Replica *r)
|
||||
/* ruv does not exist - create one */
|
||||
replica_lock(r->repl_lock);
|
||||
|
||||
- if (rc == LDAP_SUCCESS)
|
||||
- {
|
||||
- r->repl_ruv_dirty = PR_FALSE;
|
||||
- }
|
||||
- else if (rc == LDAP_NO_SUCH_OBJECT)
|
||||
+ if (rc == LDAP_NO_SUCH_OBJECT)
|
||||
{
|
||||
/* this includes an internal operation - but since this only happens
|
||||
during server startup - its ok that we have lock around it */
|
||||
rc = _replica_configure_ruv (r, PR_TRUE);
|
||||
- if (rc == 0)
|
||||
- r->repl_ruv_dirty = PR_FALSE;
|
||||
}
|
||||
- else /* error */
|
||||
+ else if (rc != LDAP_SUCCESS) /* error */
|
||||
{
|
||||
slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
|
||||
"replica_write_ruv - Failed to update RUV tombstone for %s; "
|
||||
@@ -3570,7 +3548,6 @@ replica_create_ruv_tombstone(Replica *r)
|
||||
|
||||
if (ruv_init_new(csnstr, r->repl_rid, purl, &ruv) == RUV_SUCCESS){
|
||||
r->repl_ruv = object_new((void*)ruv, (FNFree)ruv_destroy);
|
||||
- r->repl_ruv_dirty = PR_TRUE;
|
||||
return_value = LDAP_SUCCESS;
|
||||
} else {
|
||||
slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_create_ruv_tombstone - "
|
||||
@@ -3610,8 +3587,6 @@ replica_create_ruv_tombstone(Replica *r)
|
||||
slapi_add_internal_pb(pb);
|
||||
e = NULL; /* add consumes e, upon success or failure */
|
||||
slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &return_value);
|
||||
- if (return_value == LDAP_SUCCESS)
|
||||
- r->repl_ruv_dirty = PR_FALSE;
|
||||
|
||||
done:
|
||||
slapi_entry_free (e);
|
||||
@@ -3930,7 +3905,6 @@ replica_strip_cleaned_rids(Replica *r)
|
||||
ruv_get_cleaned_rids(ruv, rid);
|
||||
while(rid[i] != 0){
|
||||
ruv_delete_replica(ruv, rid[i]);
|
||||
- replica_set_ruv_dirty(r);
|
||||
if (replica_write_ruv(r)) {
|
||||
slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
|
||||
"replica_strip_cleaned_rids - Failed to write RUV\n");
|
||||
@@ -4052,15 +4026,6 @@ replica_update_ruv_consumer(Replica *r, RUV *supplier_ruv)
|
||||
}
|
||||
}
|
||||
|
||||
-void
|
||||
-replica_set_ruv_dirty(Replica *r)
|
||||
-{
|
||||
- PR_ASSERT(r);
|
||||
- replica_lock(r->repl_lock);
|
||||
- r->repl_ruv_dirty = PR_TRUE;
|
||||
- replica_unlock(r->repl_lock);
|
||||
-}
|
||||
-
|
||||
PRBool
|
||||
replica_is_state_flag_set(Replica *r, PRInt32 flag)
|
||||
{
|
||||
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||
index 814f1cac0..128c9423a 100644
|
||||
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
|
||||
@@ -1034,7 +1034,6 @@ replica_config_change_type_and_id (Replica *r, const char *new_type,
|
||||
replica_reset_csn_pl(r);
|
||||
}
|
||||
ruv_delete_replica(ruv, oldrid);
|
||||
- replica_set_ruv_dirty(r);
|
||||
cl5CleanRUV(oldrid);
|
||||
replica_set_csn_assigned(r);
|
||||
}
|
||||
@@ -1454,7 +1453,6 @@ replica_execute_cleanruv_task (Object *r, ReplicaId rid, char *returntext /* not
|
||||
return LDAP_UNWILLING_TO_PERFORM;
|
||||
}
|
||||
rc = ruv_delete_replica(local_ruv, rid);
|
||||
- replica_set_ruv_dirty(replica);
|
||||
if (replica_write_ruv(replica)) {
|
||||
slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "cleanAllRUV_task - Could not write RUV\n");
|
||||
}
|
||||
--
|
||||
2.13.6
|
||||
|
293
SOURCES/0085-Ticket-49495-Fix-memory-management-is-vattr.patch
Normal file
293
SOURCES/0085-Ticket-49495-Fix-memory-management-is-vattr.patch
Normal file
|
@ -0,0 +1,293 @@
|
|||
From d1236b0d3917b024a252b4d6acf823a975182d3b Mon Sep 17 00:00:00 2001
|
||||
From: William Brown <firstyear@redhat.com>
|
||||
Date: Mon, 11 Dec 2017 15:48:24 +0100
|
||||
Subject: [PATCH] Ticket 49495 - Fix memory management is vattr.
|
||||
|
||||
Bug Description: During the fix for
|
||||
https://pagure.io/389-ds-base/issue/49436 a issue was exposed
|
||||
in how registration of attributes to cos work. With the change
|
||||
to handle -> attr link, this exposed that cos treats each attribute
|
||||
and template pair as a new type for the handle. As aresult, this
|
||||
caused the sp_list to create a long linked list of M*N entries
|
||||
for each attr - template value. Obviously, this is extremely
|
||||
slow to traverse during a search!
|
||||
|
||||
Fix Description: Undo part of the SLL next change and convert
|
||||
to reference counting. The issue remains that there is a defect
|
||||
in how cos handles attribute registration, but this can not be
|
||||
resolved without a significant rearchitecture of the code
|
||||
related to virtual attributes.
|
||||
|
||||
https://pagure.io/389-ds-base/issue/49495
|
||||
|
||||
Author: wibrown
|
||||
|
||||
Review by: tbordaz, lkrispen (Thanks!)
|
||||
|
||||
Note: includes backport of incr and decr for rc
|
||||
---
|
||||
ldap/servers/plugins/cos/cos_cache.c | 28 ++++------
|
||||
ldap/servers/slapd/slapi-plugin.h | 21 ++++++++
|
||||
ldap/servers/slapd/slapi_counter.c | 30 +++++++++++
|
||||
ldap/servers/slapd/vattr.c | 100 +++++++++++++++++++++--------------
|
||||
4 files changed, 122 insertions(+), 57 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c
|
||||
index 0e93183d2..74261af87 100644
|
||||
--- a/ldap/servers/plugins/cos/cos_cache.c
|
||||
+++ b/ldap/servers/plugins/cos/cos_cache.c
|
||||
@@ -275,7 +275,7 @@ static Slapi_Mutex *start_lock;
|
||||
static Slapi_Mutex *stop_lock;
|
||||
static Slapi_CondVar *something_changed = NULL;
|
||||
static Slapi_CondVar *start_cond = NULL;
|
||||
-
|
||||
+static vattr_sp_handle *vattr_handle = NULL;
|
||||
|
||||
/*
|
||||
cos_cache_init
|
||||
@@ -313,6 +313,15 @@ int cos_cache_init(void)
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ if (slapi_vattrspi_register((vattr_sp_handle **)&vattr_handle,
|
||||
+ cos_cache_vattr_get,
|
||||
+ cos_cache_vattr_compare,
|
||||
+ cos_cache_vattr_types) != 0) {
|
||||
+ slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, "cos_cache_init - Cannot register as service provider\n");
|
||||
+ ret = -1;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
/* grab the views interface */
|
||||
if (slapi_apib_get_interface(Views_v1_0_GUID, &views_api)) {
|
||||
/* lets be tolerant if views is disabled */
|
||||
@@ -872,22 +881,7 @@ cos_dn_defs_cb (Slapi_Entry* e, void *callback_data)
|
||||
dnVals[valIndex]->bv_val);
|
||||
}
|
||||
|
||||
- /*
|
||||
- * Each SP_handle is associated to one and only one vattr.
|
||||
- * We could consider making this a single function rather
|
||||
- * than the double-call.
|
||||
- */
|
||||
-
|
||||
- vattr_sp_handle *vattr_handle = NULL;
|
||||
-
|
||||
- if (slapi_vattrspi_register((vattr_sp_handle **)&vattr_handle,
|
||||
- cos_cache_vattr_get,
|
||||
- cos_cache_vattr_compare,
|
||||
- cos_cache_vattr_types) != 0) {
|
||||
- slapi_log_err(SLAPI_LOG_ERR, COS_PLUGIN_SUBSYSTEM, "cos_cache_init - Cannot register as service provider for %s\n", dnVals[valIndex]->bv_val);
|
||||
- } else {
|
||||
- slapi_vattrspi_regattr((vattr_sp_handle *)vattr_handle, dnVals[valIndex]->bv_val, NULL, NULL);
|
||||
- }
|
||||
+ slapi_vattrspi_regattr((vattr_sp_handle *)vattr_handle, dnVals[valIndex]->bv_val, NULL, NULL);
|
||||
|
||||
} /* if(attrType is cosAttribute) */
|
||||
|
||||
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
|
||||
index 4084945f4..16aa1b711 100644
|
||||
--- a/ldap/servers/slapd/slapi-plugin.h
|
||||
+++ b/ldap/servers/slapd/slapi-plugin.h
|
||||
@@ -8063,6 +8063,27 @@ int slapi_is_special_rdn(const char *rdn, int flag);
|
||||
*/
|
||||
void DS_Sleep(PRIntervalTime ticks);
|
||||
|
||||
+/**
|
||||
+ * Increment a 64bitintegral atomicly
|
||||
+ *
|
||||
+ * \param ptr - pointer to integral to increment
|
||||
+ * \param memorder - __ATOMIC_RELAXED, __ATOMIC_CONSUME, __ATOMIC_ACQUIRE,
|
||||
+ * __ATOMIC_RELEASE, __ATOMIC_ACQ_REL, __ATOMIC_SEQ_CST
|
||||
+ * \return - new value of ptr
|
||||
+ */
|
||||
+uint64_t slapi_atomic_incr_64(uint64_t *ptr, int memorder);
|
||||
+
|
||||
+/**
|
||||
+ * Decrement a 64bitintegral atomicly
|
||||
+ *
|
||||
+ * \param ptr - pointer to integral to decrement
|
||||
+ * \param memorder - __ATOMIC_RELAXED, __ATOMIC_CONSUME, __ATOMIC_ACQUIRE,
|
||||
+ * __ATOMIC_RELEASE, __ATOMIC_ACQ_REL, __ATOMIC_SEQ_CST
|
||||
+ * \return - new value of ptr
|
||||
+ */
|
||||
+uint64_t slapi_atomic_decr_64(uint64_t *ptr, int memorder);
|
||||
+
|
||||
+
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
diff --git a/ldap/servers/slapd/slapi_counter.c b/ldap/servers/slapd/slapi_counter.c
|
||||
index 9904fe964..59e5223ad 100644
|
||||
--- a/ldap/servers/slapd/slapi_counter.c
|
||||
+++ b/ldap/servers/slapd/slapi_counter.c
|
||||
@@ -269,3 +269,33 @@ uint64_t slapi_counter_get_value(Slapi_Counter *counter)
|
||||
return value;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * atomic increment functions (64bit)
|
||||
+ */
|
||||
+uint64_t
|
||||
+slapi_atomic_incr_64(uint64_t *ptr, int memorder)
|
||||
+{
|
||||
+#ifdef ATOMIC_64BIT_OPERATIONS
|
||||
+ return __atomic_add_fetch_8(ptr, 1, memorder);
|
||||
+#else
|
||||
+ PRInt32 *pr_ptr = (PRInt32 *)ptr;
|
||||
+ return PR_AtomicIncrement(pr_ptr);
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * atomic decrement functions (64bit)
|
||||
+ */
|
||||
+
|
||||
+uint64_t
|
||||
+slapi_atomic_decr_64(uint64_t *ptr, int memorder)
|
||||
+{
|
||||
+#ifdef ATOMIC_64BIT_OPERATIONS
|
||||
+ return __atomic_sub_fetch_8(ptr, 1, memorder);
|
||||
+#else
|
||||
+ PRInt32 *pr_ptr = (PRInt32 *)ptr;
|
||||
+ return PR_AtomicDecrement(pr_ptr);
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+
|
||||
diff --git a/ldap/servers/slapd/vattr.c b/ldap/servers/slapd/vattr.c
|
||||
index 84e01cd62..adf44b0b6 100644
|
||||
--- a/ldap/servers/slapd/vattr.c
|
||||
+++ b/ldap/servers/slapd/vattr.c
|
||||
@@ -1529,10 +1529,12 @@ struct _vattr_sp {
|
||||
typedef struct _vattr_sp vattr_sp;
|
||||
|
||||
/* Service provider handle */
|
||||
-struct _vattr_sp_handle {
|
||||
- vattr_sp *sp;
|
||||
- struct _vattr_sp_handle *next; /* So we can link them together in the map */
|
||||
- void *hint; /* Hint to the SP */
|
||||
+struct _vattr_sp_handle
|
||||
+{
|
||||
+ vattr_sp *sp;
|
||||
+ struct _vattr_sp_handle *next; /* So we can link them together in the map */
|
||||
+ void *hint; /* Hint to the SP */
|
||||
+ uint64_t rc;
|
||||
};
|
||||
|
||||
/* Calls made by Service Providers */
|
||||
@@ -1758,7 +1760,7 @@ is a separate thing in the insterests of stability.
|
||||
|
||||
*/
|
||||
|
||||
-#define VARRT_MAP_HASHTABLE_SIZE 10
|
||||
+#define VARRT_MAP_HASHTABLE_SIZE 32
|
||||
|
||||
/* Attribute map oject */
|
||||
/* Needs to contain: a linked list of pointers to provider handles handles,
|
||||
@@ -1849,7 +1851,10 @@ vattr_map_entry_free(vattr_map_entry *vae)
|
||||
vattr_sp_handle *list_entry = vae->sp_list;
|
||||
while (list_entry != NULL) {
|
||||
vattr_sp_handle *next_entry = list_entry->next;
|
||||
- slapi_ch_free((void **)&list_entry);
|
||||
+ if (slapi_atomic_decr_64(&(list_entry->rc), __ATOMIC_RELAXED) == 0) {
|
||||
+ /* Only free on RC 0 */
|
||||
+ slapi_ch_free((void **)&list_entry);
|
||||
+ }
|
||||
list_entry = next_entry;
|
||||
}
|
||||
slapi_ch_free_string(&(vae->type_name));
|
||||
@@ -2268,41 +2273,56 @@ to handle the calls on it, but return nothing */
|
||||
*
|
||||
* Better idea, is that regattr should just take the fn pointers
|
||||
* and callers never *see* the sp_handle structure at all.
|
||||
+ *
|
||||
+ * This leaves us with some quirks today. First: if you have plugin A
|
||||
+ * and B, A registers attr 1 and B 1 and 2, it's possible that if you
|
||||
+ * register A1 first, then B1, you have B->A in next. Then when you
|
||||
+ * register B2, because we take 0==result from map_lookup, we add sp
|
||||
+ * "as is" to the map. This means that B2 now has the same next to A1
|
||||
+ * handle. This won't add a bug, because A1 won't be able to service the
|
||||
+ * attr, but it could cause some head scratching ...
|
||||
+ *
|
||||
+ * Again, to fix this, the whole vattr external interface needs a
|
||||
+ * redesign ... :(
|
||||
*/
|
||||
-
|
||||
-int vattr_map_sp_insert(char *type_to_add, vattr_sp_handle *sp, void *hint)
|
||||
-{
|
||||
- int result = 0;
|
||||
- vattr_map_entry *map_entry = NULL;
|
||||
- /* Is this type already there ? */
|
||||
- result = vattr_map_lookup(type_to_add,&map_entry);
|
||||
- /* If it is, add this SP to the list, safely even if readers are traversing the list at the same time */
|
||||
- if (0 == result) {
|
||||
- int found = 0;
|
||||
- vattr_sp_handle *list_entry = NULL;
|
||||
- /* Walk the list checking that the daft SP isn't already here */
|
||||
- for (list_entry = map_entry->sp_list ; list_entry; list_entry = list_entry->next) {
|
||||
- if (list_entry == sp) {
|
||||
- found = 1;
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
- /* If it is, we do nothing */
|
||||
- if(found) {
|
||||
- return 0;
|
||||
- }
|
||||
- /* We insert the SP handle into the linked list at the head */
|
||||
- sp->next = map_entry->sp_list;
|
||||
- map_entry->sp_list = sp;
|
||||
- } else {
|
||||
- /* If not, add it */
|
||||
- map_entry = vattr_map_entry_new(type_to_add,sp,hint);
|
||||
- if (NULL == map_entry) {
|
||||
- return ENOMEM;
|
||||
- }
|
||||
- return vattr_map_insert(map_entry);
|
||||
- }
|
||||
- return 0;
|
||||
+int
|
||||
+vattr_map_sp_insert(char *type_to_add, vattr_sp_handle *sp, void *hint)
|
||||
+{
|
||||
+ int result = 0;
|
||||
+ vattr_map_entry *map_entry = NULL;
|
||||
+ /* Is this type already there ? */
|
||||
+ result = vattr_map_lookup(type_to_add, &map_entry);
|
||||
+ /* If it is, add this SP to the list, safely even if readers are traversing the list at the same time */
|
||||
+ if (0 == result) {
|
||||
+ int found = 0;
|
||||
+ vattr_sp_handle *list_entry = NULL;
|
||||
+ /* Walk the list checking that the daft SP isn't already here */
|
||||
+ for (list_entry = map_entry->sp_list; list_entry; list_entry = list_entry->next) {
|
||||
+ if (list_entry == sp) {
|
||||
+ found = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ /* If it is, we do nothing */
|
||||
+ if (found) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ /* Increase the ref count of the sphandle */
|
||||
+ slapi_atomic_incr_64(&(sp->rc), __ATOMIC_RELAXED);
|
||||
+ /* We insert the SP handle into the linked list at the head */
|
||||
+ sp->next = map_entry->sp_list;
|
||||
+ map_entry->sp_list = sp;
|
||||
+ } else {
|
||||
+ /* If not, add it */
|
||||
+ /* Claim a reference on the sp ... */
|
||||
+ slapi_atomic_incr_64(&(sp->rc), __ATOMIC_RELAXED);
|
||||
+ map_entry = vattr_map_entry_new(type_to_add, sp, hint);
|
||||
+ if (NULL == map_entry) {
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+ return vattr_map_insert(map_entry);
|
||||
+ }
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
From 040c492b4beb0efcd34b8420f682187441767055 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Reynolds <mreynolds@redhat.com>
|
||||
Date: Tue, 16 Jan 2018 09:46:49 -0500
|
||||
Subject: [PATCH] CVE-2017-15134 389-ds-base: Remote DoS via search filters in
|
||||
slapi_filter_sprintf
|
||||
|
||||
Description: Improper handling of a search filter in slapi_filter_sprintf
|
||||
in slapd/util.c can lead to remote server crash and denial
|
||||
of service.
|
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1529117
|
||||
---
|
||||
ldap/servers/slapd/util.c | 36 +++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 31 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/ldap/servers/slapd/util.c b/ldap/servers/slapd/util.c
|
||||
index 4ff6d4141..ffeeff6f3 100644
|
||||
--- a/ldap/servers/slapd/util.c
|
||||
+++ b/ldap/servers/slapd/util.c
|
||||
@@ -224,9 +224,10 @@ escape_string_for_filename(const char *str, char buf[BUFSIZ])
|
||||
|
||||
struct filter_ctx {
|
||||
char *buf;
|
||||
- char attr[ATTRSIZE];
|
||||
+ char *attr;
|
||||
int attr_position;
|
||||
int attr_found;
|
||||
+ size_t attr_size;
|
||||
int buf_size;
|
||||
int buf_len;
|
||||
int next_arg_needs_esc_norm;
|
||||
@@ -265,7 +266,7 @@ filter_stuff_func(void *arg, const char *val, PRUint32 slen)
|
||||
* Start collecting the attribute name so we can use the correct
|
||||
* syntax normalization func.
|
||||
*/
|
||||
- if(ctx->attr_found == 0 && ctx->attr_position < (ATTRSIZE - 1)){
|
||||
+ if(ctx->attr_found == 0 && ctx->attr_position < (ctx->attr_size - 1)) {
|
||||
if(ctx->attr[0] == '\0'){
|
||||
if(strstr(val,"=")){
|
||||
/* we have an attr we need to record */
|
||||
@@ -279,6 +280,14 @@ filter_stuff_func(void *arg, const char *val, PRUint32 slen)
|
||||
* attr with val. The next pass should be '=', otherwise we will
|
||||
* reset it.
|
||||
*/
|
||||
+ if (slen > ctx->attr_size) {
|
||||
+ if (ctx->attr_size == ATTRSIZE) {
|
||||
+ ctx->attr = slapi_ch_calloc(sizeof(char), slen+1);
|
||||
+ } else {
|
||||
+ ctx->attr = slapi_ch_realloc(ctx->attr, sizeof(char) * (slen+1));
|
||||
+ }
|
||||
+ ctx->attr_size = slen+1;
|
||||
+ }
|
||||
memcpy(ctx->attr, val, slen);
|
||||
ctx->attr_position = slen;
|
||||
}
|
||||
@@ -288,9 +297,20 @@ filter_stuff_func(void *arg, const char *val, PRUint32 slen)
|
||||
} else {
|
||||
if(special_attr_char(val[0])){
|
||||
/* this is not an attribute, we should not be collecting this, reset everything */
|
||||
- memset(ctx->attr, '\0', ATTRSIZE);
|
||||
+ memset(ctx->attr, '\0', ctx->attr_size);
|
||||
ctx->attr_position = 0;
|
||||
} else {
|
||||
+ /* we can be adding char by char and overrun allocated size */
|
||||
+ if (ctx->attr_position >= ctx->attr_size) {
|
||||
+ if (ctx->attr_size == ATTRSIZE) {
|
||||
+ char *ctxattr = slapi_ch_calloc(sizeof(char), ctx->attr_size + ATTRSIZE);
|
||||
+ memcpy(ctxattr, ctx->attr, ctx->attr_size);
|
||||
+ ctx->attr = ctxattr;
|
||||
+ } else {
|
||||
+ ctx->attr = slapi_ch_realloc(ctx->attr, sizeof(char) * (ctx->attr_size + ATTRSIZE));
|
||||
+ }
|
||||
+ ctx->attr_size = ctx->attr_size + ATTRSIZE;
|
||||
+ }
|
||||
memcpy(ctx->attr + ctx->attr_position, val, 1);
|
||||
ctx->attr_position++;
|
||||
}
|
||||
@@ -363,7 +383,7 @@ filter_stuff_func(void *arg, const char *val, PRUint32 slen)
|
||||
ctx->next_arg_needs_esc_norm = 0;
|
||||
ctx->attr_found = 0;
|
||||
ctx->attr_position = 0;
|
||||
- memset(ctx->attr, '\0', ATTRSIZE);
|
||||
+ memset(ctx->attr, '\0', ctx->attr_size);
|
||||
slapi_ch_free_string(&buf);
|
||||
|
||||
return filter_len;
|
||||
@@ -402,13 +422,15 @@ slapi_filter_sprintf(const char *fmt, ...)
|
||||
{
|
||||
struct filter_ctx ctx = {0};
|
||||
va_list args;
|
||||
+ char attr_static[ATTRSIZE] = {0};
|
||||
char *buf;
|
||||
int rc;
|
||||
|
||||
buf = slapi_ch_calloc(sizeof(char), FILTER_BUF + 1);
|
||||
ctx.buf = buf;
|
||||
- memset(ctx.attr,'\0', ATTRSIZE);
|
||||
ctx.attr_position = 0;
|
||||
+ ctx.attr = attr_static;
|
||||
+ ctx.attr_size = ATTRSIZE;
|
||||
ctx.attr_found = 0;
|
||||
ctx.buf_len = FILTER_BUF;
|
||||
ctx.buf_size = 0;
|
||||
@@ -424,6 +446,10 @@ slapi_filter_sprintf(const char *fmt, ...)
|
||||
}
|
||||
va_end(args);
|
||||
|
||||
+ if (ctx.attr_size > ATTRSIZE) {
|
||||
+ slapi_ch_free_string(&ctx.attr);
|
||||
+ }
|
||||
+
|
||||
return ctx.buf;
|
||||
}
|
||||
|
||||
--
|
||||
2.13.6
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
Summary: 389 Directory Server (base)
|
||||
Name: 389-ds-base
|
||||
Version: 1.3.6.1
|
||||
Release: %{?relprefix}24%{?prerel}%{?dist}
|
||||
Release: %{?relprefix}26%{?prerel}%{?dist}
|
||||
License: GPLv3+
|
||||
URL: https://www.port389.org/
|
||||
Group: System Environment/Daemons
|
||||
|
@ -216,6 +216,10 @@ Patch79: 0079-Ticket-49439-cleanallruv-is-not-logging-information.patch
|
|||
Patch80: 0080-Ticket-49436-double-free-in-COS-in-some-conditions.patch
|
||||
Patch81: 0081-Ticket-49441-Import-crashes-with-large-indexed-binar.patch
|
||||
Patch82: 0082-Ticket-49431-replicated-MODRDN-fails-breaking-replic.patch
|
||||
Patch83: 0083-Ticket-49410-opened-connection-can-remain-no-longer-.patch
|
||||
Patch84: 0084-Ticket-48118-backport-changelog-can-be-erronously-re.patch
|
||||
Patch85: 0085-Ticket-49495-Fix-memory-management-is-vattr.patch
|
||||
Patch86: 0086-CVE-2017-15134-389-ds-base-Remote-DoS-via-search-fil.patch
|
||||
|
||||
%description
|
||||
389 Directory Server is an LDAPv3 compliant server. The base package includes
|
||||
|
@ -368,6 +372,10 @@ cp %{SOURCE2} README.devel
|
|||
%patch80 -p1
|
||||
%patch81 -p1
|
||||
%patch82 -p1
|
||||
%patch83 -p1
|
||||
%patch84 -p1
|
||||
%patch85 -p1
|
||||
%patch86 -p1
|
||||
|
||||
%build
|
||||
|
||||
|
@ -600,6 +608,16 @@ fi
|
|||
%{_sysconfdir}/%{pkgname}/dirsrvtests
|
||||
|
||||
%changelog
|
||||
* Tue Jan 16 2018 Mark Reynolds <mreynolds@redhat.com> - 1.3.6.1-26
|
||||
- Bump version to 1.3.6.1-25
|
||||
- Resolves: Bug 1534430 - crash in slapi_filter_sprintf
|
||||
|
||||
* Mon Dec 18 2017 Mark Reynolds <mreynolds@redhat.com> - 1.3.6.1-25
|
||||
- Bump version to 1.3.6.1-25
|
||||
- Resolves: Bug 1526928 - search with CoS attribute is getting slower after modifying/adding CosTemplate
|
||||
- Resolves: Bug 1523505 - opened connection are hanging, no longer poll
|
||||
- Resolves: Bug 1523507 - IPA server replication broken, after DS stop-start, due to changelog reset
|
||||
|
||||
* Fri Nov 10 2017 Mark Reynolds <mreynolds@redhat.com> - 1.3.6.1-24
|
||||
- Bump version to 1.3.6.1-24
|
||||
- Resolves: Bug 1508978 - replicated MODRDN fails breaking replication
|
||||
|
|
Loading…
Add table
Reference in a new issue