]> git.ipfire.org Git - thirdparty/haproxy.git/commit
BUG/MEDIUM: stick-table: Decrement the ref count inside lock to kill a session
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 25 Jun 2024 06:22:58 +0000 (08:22 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 26 Jun 2024 10:05:37 +0000 (12:05 +0200)
commit9357873641c5de29b169848fc1c808747818a1eb
tree91ec7909001eca8ef789e7f5e75c6541596a33e4
parentbcf98c9b5f00855cf82eff0bcb71f142cb234bb2
BUG/MEDIUM: stick-table: Decrement the ref count inside lock to kill a session

When we try to kill a session, the shard must be locked before decrementing
the ref count on the session. Otherwise, the ref count can fall to 0 and a
purge task (stktable_trash_oldest or process_table_expire) may release the
session before we have the opportunity to acquire the lock on the shard to
effectively kill the session. This could lead to a double free.

Here is the scenario:

    Thread 1                                 Thread 2

  sktsess_kill(ts)
    if (ATOMIC_DEC(&ts->ref_cnt) != 0)
        return
                   /* here the ref count is 0 */

                                       stktable_trash_oldest()
                                          LOCK(&sh_lock)
                                          if (!ATOMIC_LOAD(&ts->ref_cnf))
                                              __stksess_free(ts)
                                          UNLOCK(&sh_lock)

                  /* here the session was released */
    LOCK(&sh_lock)
    __stksess_free(ts)  <--- double free
    UNLOCK(&sh_lock)

The bug was introduced in 2.9 by the commit 7968fe3889 ("MEDIUM:
stick-table: change the ref_cnt atomically"). The ref count must be
decremented inside the lock for stksess_kill() and sktsess_kill_if_expired()
function.

This patch should fix the issue #2611. It must be backported as far as 2.9. On
the 2.9, there is no sharding. All the table is locked. The patch will have to
be adapted.
include/haproxy/stick_table.h
src/stick_table.c