Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Joe Martin
OpenLDAP
Commits
241f65b9
Commit
241f65b9
authored
Apr 20, 2018
by
Ondřej Kuzník
Browse files
Fix a race in managing b_dns_req
parent
f4a2fdd4
Changes
1
Hide whitespace changes
Inline
Side-by-side
servers/lloadd/backend.c
View file @
241f65b9
...
...
@@ -93,9 +93,22 @@ upstream_name_cb( int result, struct evutil_addrinfo *res, void *arg )
ber_socket_t
s
=
AC_SOCKET_INVALID
;
int
rc
;
ldap_pvt_thread_mutex_lock
(
&
b
->
b_mutex
);
if
(
result
==
EVUTIL_EAI_CANCEL
)
{
Debug
(
LDAP_DEBUG_ANY
,
"upstream_name_cb: "
"cancelled
\n
"
);
return
;
}
ldap_pvt_thread_mutex_lock
(
&
b
->
b_mutex
);
/* We were already running when backend_reset tried to cancel us, but were
* already stuck waiting for the mutex, nothing to do and b_opening has
* been decremented as well */
if
(
b
->
b_dns_req
==
NULL
)
{
ldap_pvt_thread_mutex_unlock
(
&
b
->
b_mutex
);
return
;
}
b
->
b_dns_req
=
NULL
;
if
(
result
||
!
res
)
{
Debug
(
LDAP_DEBUG_ANY
,
"upstream_name_cb: "
"name resolution failed for backend '%s': %s
\n
"
,
...
...
@@ -170,9 +183,7 @@ fail:
b
->
b_opening
--
;
b
->
b_failed
++
;
ldap_pvt_thread_mutex_unlock
(
&
b
->
b_mutex
);
if
(
result
!=
EVUTIL_EAI_CANCEL
)
{
backend_retry
(
b
);
}
backend_retry
(
b
);
if
(
res
)
{
evutil_freeaddrinfo
(
res
);
}
...
...
@@ -331,24 +342,29 @@ backend_connect( evutil_socket_t s, short what, void *arg )
{
struct
evutil_addrinfo
hints
=
{};
LloadBackend
*
b
=
arg
;
struct
evdns_getaddrinfo_request
*
request
,
*
placeholder
;
char
*
hostname
;
ldap_pvt_thread_mutex_lock
(
&
b
->
b_mutex
);
assert
(
b
->
b_dns_req
==
NULL
);
if
(
b
->
b_cookie
)
{
b
->
b_cookie
=
NULL
;
}
if
(
slapd_shutdown
)
{
Debug
(
LDAP_DEBUG_CONNS
,
"backend_connect: "
"doing nothing, shutdown in progress
\n
"
);
b
->
b_opening
--
;
ldap_pvt_thread_mutex_unlock
(
&
b
->
b_mutex
);
return
;
}
ldap_pvt_thread_mutex_lock
(
&
b
->
b_mutex
);
Debug
(
LDAP_DEBUG_CONNS
,
"backend_connect: "
"%sattempting connection to %s
\n
"
,
(
what
&
EV_TIMEOUT
)
?
"retry timeout finished, "
:
""
,
b
->
b_host
);
if
(
b
->
b_cookie
)
{
b
->
b_cookie
=
NULL
;
}
#ifdef LDAP_PF_LOCAL
if
(
b
->
b_proto
==
LDAP_PROTO_IPC
)
{
struct
sockaddr_un
addr
;
...
...
@@ -420,11 +436,31 @@ backend_connect( evutil_socket_t s, short what, void *arg )
hints
.
ai_protocol
=
IPPROTO_TCP
;
hostname
=
b
->
b_host
;
/*
* Picking any value on the stack. This is unique to our thread without
* having to call ldap_pvt_thread_self.
* We might have to revert to using ldap_pvt_thread_self eventually since
* this betrays where exactly our stack lies - potentially weakening some
* protections like ASLR.
*/
placeholder
=
(
struct
evdns_getaddrinfo_request
*
)
&
request
;
b
->
b_dns_req
=
placeholder
;
ldap_pvt_thread_mutex_unlock
(
&
b
->
b_mutex
);
assert
(
b
->
b_dns_req
==
NULL
);
b
->
b_dns_req
=
evdns_getaddrinfo
(
request
=
evdns_getaddrinfo
(
dnsbase
,
hostname
,
NULL
,
&
hints
,
upstream_name_cb
,
b
);
ldap_pvt_thread_mutex_lock
(
&
b
->
b_mutex
);
assert
(
request
||
b
->
b_dns_req
!=
placeholder
);
/* Record the request, unless upstream_name_cb or another thread
* cleared it. Another thread is usually backend_reset or backend_connect
* if upstream_name_cb finished and scheduled another one */
if
(
b
->
b_dns_req
==
placeholder
)
{
b
->
b_dns_req
=
request
;
}
ldap_pvt_thread_mutex_unlock
(
&
b
->
b_mutex
);
return
;
fail:
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment