|
|
b045b9 |
From dd12327d1523f3ff9d6ae8b44b640fb9d0d2d53b Mon Sep 17 00:00:00 2001
|
|
|
b045b9 |
From: Mark Reynolds <mreynolds@redhat.com>
|
|
|
b045b9 |
Date: Mon, 19 Feb 2018 10:44:36 -0500
|
|
|
b045b9 |
Subject: [PATCH] Ticket 49296 - Fix race condition in connection code with
|
|
|
b045b9 |
anonymous limits
|
|
|
b045b9 |
|
|
|
b045b9 |
Bug Description: When a connection first comes in we set the anonymous
|
|
|
b045b9 |
resource limits (if set) before we do anything else. The
|
|
|
b045b9 |
way we check if the connection is "new" was flawed. It
|
|
|
b045b9 |
assumed the connection was new if no operations were
|
|
|
b045b9 |
completed yet, but there was a small window between sending
|
|
|
b045b9 |
the result and setting that the operation completed in the
|
|
|
b045b9 |
connection struct.
|
|
|
b045b9 |
|
|
|
b045b9 |
So on a connection that binds and then does a search, when
|
|
|
b045b9 |
the server sends the bind result the client sends the search,
|
|
|
b045b9 |
but the search op/activity can be picked up before we set
|
|
|
b045b9 |
c_opscompleted. This opens a window where the code thinks
|
|
|
b045b9 |
the search op is the first op(new connection), and it incorrectly
|
|
|
b045b9 |
sets the anonymous limits for the bind dn.
|
|
|
b045b9 |
|
|
|
b045b9 |
Fix description: Do not use c_opscompleted to determine if a connection is new,
|
|
|
b045b9 |
instead use a new flag to set the connection "initialized",
|
|
|
b045b9 |
which prevents the race condition.
|
|
|
b045b9 |
|
|
|
b045b9 |
https://pagure.io/389-ds-base/issue/49296
|
|
|
b045b9 |
|
|
|
b045b9 |
Reviewed by: firstyear(Thanks!)
|
|
|
b045b9 |
|
|
|
b045b9 |
(cherry picked from commit 0d5214d08e6b5b39fb9d5ef5cf3d8834574954f1)
|
|
|
b045b9 |
---
|
|
|
b045b9 |
ldap/servers/slapd/connection.c | 12 +++++++++++-
|
|
|
b045b9 |
ldap/servers/slapd/slap.h | 7 +++----
|
|
|
b045b9 |
2 files changed, 14 insertions(+), 5 deletions(-)
|
|
|
b045b9 |
|
|
|
b045b9 |
diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c
|
|
|
b045b9 |
index 5d2b64ed2..5ca32a333 100644
|
|
|
b045b9 |
--- a/ldap/servers/slapd/connection.c
|
|
|
b045b9 |
+++ b/ldap/servers/slapd/connection.c
|
|
|
b045b9 |
@@ -217,6 +217,7 @@ connection_cleanup(Connection *conn)
|
|
|
b045b9 |
conn->c_connid = 0;
|
|
|
b045b9 |
conn->c_opsinitiated = 0;
|
|
|
b045b9 |
conn->c_opscompleted = 0;
|
|
|
b045b9 |
+ conn->c_anonlimits_set = 0;
|
|
|
b045b9 |
conn->c_threadnumber = 0;
|
|
|
b045b9 |
conn->c_refcnt = 0;
|
|
|
b045b9 |
conn->c_idlesince = 0;
|
|
|
b045b9 |
@@ -1549,7 +1550,9 @@ connection_threadmain()
|
|
|
b045b9 |
g_decr_active_threadcnt();
|
|
|
b045b9 |
return;
|
|
|
b045b9 |
}
|
|
|
b045b9 |
- if (pb_conn->c_opscompleted == 0) {
|
|
|
b045b9 |
+
|
|
|
b045b9 |
+ PR_EnterMonitor(pb_conn->c_mutex);
|
|
|
b045b9 |
+ if (pb_conn->c_anonlimits_set == 0) {
|
|
|
b045b9 |
/*
|
|
|
b045b9 |
* We have a new connection, set the anonymous reslimit idletimeout
|
|
|
b045b9 |
* if applicable.
|
|
|
b045b9 |
@@ -1568,7 +1571,14 @@ connection_threadmain()
|
|
|
b045b9 |
}
|
|
|
b045b9 |
}
|
|
|
b045b9 |
slapi_ch_free_string(&anon_dn);
|
|
|
b045b9 |
+ /*
|
|
|
b045b9 |
+ * Set connection as initialized to avoid setting anonymous limits
|
|
|
b045b9 |
+ * multiple times on the same connection
|
|
|
b045b9 |
+ */
|
|
|
b045b9 |
+ pb_conn->c_anonlimits_set = 1;
|
|
|
b045b9 |
}
|
|
|
b045b9 |
+ PR_ExitMonitor(pb_conn->c_mutex);
|
|
|
b045b9 |
+
|
|
|
b045b9 |
if (connection_call_io_layer_callbacks(pb_conn)) {
|
|
|
b045b9 |
slapi_log_err(SLAPI_LOG_ERR, "connection_threadmain",
|
|
|
b045b9 |
"Could not add/remove IO layers from connection\n");
|
|
|
b045b9 |
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
|
|
|
b045b9 |
index 9b10aa19e..03355f5fe 100644
|
|
|
b045b9 |
--- a/ldap/servers/slapd/slap.h
|
|
|
b045b9 |
+++ b/ldap/servers/slapd/slap.h
|
|
|
b045b9 |
@@ -1616,6 +1616,7 @@ typedef struct conn
|
|
|
b045b9 |
PRUint64 c_maxthreadsblocked; /* # of operations blocked by maxthreads */
|
|
|
b045b9 |
int c_opsinitiated; /* # ops initiated/next op id */
|
|
|
b045b9 |
PRInt32 c_opscompleted; /* # ops completed */
|
|
|
b045b9 |
+ uint64_t c_anonlimits_set; /* default anon limits are set */
|
|
|
b045b9 |
PRInt32 c_threadnumber; /* # threads used in this conn */
|
|
|
b045b9 |
int c_refcnt; /* # ops refering to this conn */
|
|
|
b045b9 |
PRMonitor *c_mutex; /* protect each conn structure; need to be re-entrant */
|
|
|
b045b9 |
@@ -1623,10 +1624,8 @@ typedef struct conn
|
|
|
b045b9 |
time_t c_idlesince; /* last time of activity on conn */
|
|
|
b045b9 |
int c_idletimeout; /* local copy of idletimeout */
|
|
|
b045b9 |
int c_idletimeout_handle; /* the resource limits handle */
|
|
|
b045b9 |
- Conn_private *c_private; /* data which is not shared outside*/
|
|
|
b045b9 |
- /* connection.c */
|
|
|
b045b9 |
- int c_flags; /* Misc flags used only for SSL */
|
|
|
b045b9 |
- /* status currently */
|
|
|
b045b9 |
+ Conn_private *c_private; /* data which is not shared outside connection.c */
|
|
|
b045b9 |
+ int c_flags; /* Misc flags used only for SSL status currently */
|
|
|
b045b9 |
int c_needpw; /* need new password */
|
|
|
b045b9 |
CERTCertificate *c_client_cert; /* Client's Cert */
|
|
|
b045b9 |
PRFileDesc *c_prfd; /* NSPR 2.1 FileDesc */
|
|
|
b045b9 |
--
|
|
|
b045b9 |
2.13.6
|
|
|
b045b9 |
|