]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: checks: Make sure we set the task affinity just before connecting.
authorOlivier Houchard <ohouchard@haproxy.com>
Fri, 29 Nov 2019 15:18:51 +0000 (16:18 +0100)
committerOlivier Houchard <cognet@ci0.org>
Thu, 5 Dec 2019 14:31:44 +0000 (15:31 +0100)
In process_chk_conn(), make sure we set the task affinity to the current
thread as soon as we're attempting a connection (and reset the affinity to
"any thread" if we detect a failure).
We used to only set the task affinity if connect_conn_chk() returned
SF_ERR_NONE, however for TCP checks, SF_ERR_UP is returned, so for those
checks, the task could still run on any thread, and this could lead to a
race condition where the connection runs on one thread, while the task runs
on another one, which could create random memory corruption and/or crashes.
This may fix github issue #369.

This should be backported to 2.1, 2.0 and 1.9.

src/checks.c

index 909bd52f22fb89a9bf342e2113aee809c4728224..aa93bab48fa39c1b817f23d7a5f79818d9a5ac86 100644 (file)
@@ -2245,6 +2245,7 @@ static struct task *process_chk_conn(struct task *t, void *context, unsigned sho
                b_reset(&check->bi);
                b_reset(&check->bo);
 
+               task_set_affinity(t, tid_bit);
                ret = connect_conn_chk(t);
                cs = check->cs;
                conn = cs_conn(cs);
@@ -2276,7 +2277,6 @@ static struct task *process_chk_conn(struct task *t, void *context, unsigned sho
                                        __event_srv_chk_r(cs);
                        }
 
-                       task_set_affinity(t, tid_bit);
                        goto reschedule;
 
                case SF_ERR_SRVTO: /* ETIMEDOUT */
@@ -2298,6 +2298,7 @@ static struct task *process_chk_conn(struct task *t, void *context, unsigned sho
                }
 
                /* here, we have seen a synchronous error, no fd was allocated */
+               task_set_affinity(t, MAX_THREADS_MASK);
                if (cs) {
                        if (check->wait_list.events)
                                cs->conn->xprt->unsubscribe(cs->conn,