From fd9f8f51172566288fec0f49fd1463dfaf8dfcef Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Sat, 17 Feb 2018 17:20:41 -0500 Subject: [PATCH] Ticket 49296 - Fix race condition in connection code with anonymous limits Bug Description: When a connection first comes in we set the anonymous resource limits (if set) before we do anything else. The way we check if the connection is "new" was flawed. It assumed the connection was new if no operations were completed yet, but there was a small window between sending the result and setting that the operation completed in the connection struct. So on a connection that binds and then does a search, when the server sends the bind result the client sends the search, but the search op/activity can be picked up before we set c_opscompleted. This opens a window where the code thinks the search op is the first op(new connection), and it incorrectly sets the anonymous limits for the bind dn. Fix description: Do not use c_opscompleted to determine if a connection is new, instead use a new flag to set the connection "initialized", which prevents the race condition. https://pagure.io/389-ds-base/issue/49296 Reviewed by: ? --- ldap/servers/slapd/connection.c | 6 +++++- ldap/servers/slapd/slap.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c index 5d2b64ed2..f5e417a3c 100644 --- a/ldap/servers/slapd/connection.c +++ b/ldap/servers/slapd/connection.c @@ -217,6 +217,7 @@ connection_cleanup(Connection *conn) conn->c_connid = 0; conn->c_opsinitiated = 0; conn->c_opscompleted = 0; + conn->c_inited = 0; conn->c_threadnumber = 0; conn->c_refcnt = 0; conn->c_idlesince = 0; @@ -1549,7 +1550,7 @@ connection_threadmain() g_decr_active_threadcnt(); return; } - if (pb_conn->c_opscompleted == 0) { + if (pb_conn->c_inited == 0) { /* * We have a new connection, set the anonymous reslimit idletimeout * if applicable. @@ -1568,6 +1569,9 @@ connection_threadmain() } } slapi_ch_free_string(&anon_dn); + /* Set connection as initialized to avoid race condition with setting + * anonymous limits multiple times on the same connection */ + pb_conn->c_inited = 1; } if (connection_call_io_layer_callbacks(pb_conn)) { slapi_log_err(SLAPI_LOG_ERR, "connection_threadmain", diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h index 70605f91e..4491b57c6 100644 --- a/ldap/servers/slapd/slap.h +++ b/ldap/servers/slapd/slap.h @@ -1616,6 +1616,7 @@ typedef struct conn PRUint64 c_maxthreadsblocked; /* # of operations blocked by maxthreads */ int c_opsinitiated; /* # ops initiated/next op id */ PRInt32 c_opscompleted; /* # ops completed */ + PRInt32 c_inited; /* Connection is initialized */ PRInt32 c_threadnumber; /* # threads used in this conn */ int c_refcnt; /* # ops refering to this conn */ PRMonitor *c_mutex; /* protect each conn structure; need to be re-entrant */ -- 2.13.6