import 389-ds-base-1.3.6.1-26.el7_4

This commit is contained in:
CentOS Sources 2018-01-25 04:28:42 -05:00
parent b69e4737bd
commit a6639136ef
5 changed files with 724 additions and 1 deletions

View file

@ -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

View file

@ -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

View 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

View file

@ -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

View file

@ -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