|
|
- commit 6d79cedaaa4a16b2f42d2bf2bc25772a51354e91
- Author: Willy Tarreau <w@1wt.eu>
- Date: Wed Jul 24 17:42:44 2019 +0200
-
- BUG/MINOR: proxy: always lock stop_proxy()
-
- There is one unprotected call to stop_proxy() from the manage_proxy()
- task, so there is a single caller by definition, but there is also
- another such call from the CLI's "shutdown frontend" parser. This
- one does it under the proxy's lock but the first one doesn't use it.
- Thus it is theorically possible to corrupt the list of listeners in a
- proxy by issuing "shutdown frontend" and SIGUSR1 exactly at the same
- time. While it sounds particularly contrived or stupid, it could
- possibly happen with automated tools that would send actions via
- various channels. This could cause the process to loop forever or
- to crash and thus stop faster than expected.
-
- This might be backported as far as 1.8.
-
- (cherry picked from commit 3de3cd4d9761324b31d23eb2c4a9434ed33801b8)
- Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
-
- diff --git a/src/proxy.c b/src/proxy.c
- index f669ebf1..ae761ead 100644
- --- a/src/proxy.c
- +++ b/src/proxy.c
- @@ -1258,13 +1258,16 @@ void zombify_proxy(struct proxy *p)
- * to be called when going down in order to release the ports so that another
- * process may bind to them. It must also be called on disabled proxies at the
- * end of start-up. If all listeners are closed, the proxy is set to the
- - * PR_STSTOPPED state.
- + * PR_STSTOPPED state. The function takes the proxy's lock so it's safe to
- + * call from multiple places.
- */
- void stop_proxy(struct proxy *p)
- {
- struct listener *l;
- int nostop = 0;
-
- + HA_SPIN_LOCK(PROXY_LOCK, &p->lock);
- +
- list_for_each_entry(l, &p->conf.listeners, by_fe) {
- if (l->options & LI_O_NOSTOP) {
- HA_ATOMIC_ADD(&unstoppable_jobs, 1);
- @@ -1278,6 +1281,8 @@ void stop_proxy(struct proxy *p)
- }
- if (!nostop)
- p->state = PR_STSTOPPED;
- +
- + HA_SPIN_UNLOCK(PROXY_LOCK, &p->lock);
- }
-
- /* This function resumes listening on the specified proxy. It scans all of its
- @@ -2110,10 +2115,7 @@ static int cli_parse_shutdown_frontend(char **args, char *payload, struct appctx
- send_log(px, LOG_WARNING, "Proxy %s stopped (FE: %lld conns, BE: %lld conns).\n",
- px->id, px->fe_counters.cum_conn, px->be_counters.cum_conn);
-
- - HA_SPIN_LOCK(PROXY_LOCK, &px->lock);
- stop_proxy(px);
- - HA_SPIN_UNLOCK(PROXY_LOCK, &px->lock);
- -
- return 1;
- }
-
|