]> git.kaiwu.me - haproxy.git/commit
BUG/MEDIUM: hlua: Never release a cosocket applet from the GC
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 4 Sep 2026 07:45:02 +0000 (09:45 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 4 Sep 2026 08:23:38 +0000 (10:23 +0200)
commit23ebd0e959fff26321e6d384595a1f8afb198f27
tree8b95b5c92c2f0348fade03ce82f95cdcaba2e7f0
parentfc5ad42d8f52e3c9e82f192ef0d6719952915656
BUG/MEDIUM: hlua: Never release a cosocket applet from the GC

The commit 38534d344b ("BUG/MEDIUM: hlua: Be able to garbage collect
uninitialized lua sockets") introduced a regression, leading to UAF
accesses.

Indeed, with a shared lua state, the garbage collector can be run on any
thread. So for a script using cosocket loaded via "lua-load" directive, the
lua socket garbage collector can run on any thread. So here there were two
problems:

  * appctx_free() must only be called by the thread owning the applet. It
    destroys the applet's task and releases the memory to the thread-local
    pool cache. Here it was possible to call appctx_free() from any other
    thread.

  * All other accesses to the applet's context were performed after the xref
    was disconnected. However, once disconnected, the applet is free to be
    released at any instant by the thread owning it, because
    hlua_socket_release() no longer finds any peer. Because the cosocket
    context is part of the applet's context, this was a use-after-free.

So now, the GC only signals the applet it must die and wakes it up, exactly
like hlua_socket_close_helper() already does, and it does so before
disconnecting the xref. This way:

  * The applet is always released by the thread owning it.

  * Because the work is performed before the xref is disconnected, a
    concurrent hlua_socket_release() is stalled on the xref lock and cannot
    release the applet in our back.

Note this also fixes the same issue in hlua_socket_close_helper(), which
still wakes up a possibly uninitialized applet. Closing a lua socket that
was never connected ("core.tcp():close()") should be enough to trigger it.

Thank you to Red Hat and AISLE Research for reporting this.

This patch must be backported to all stable versions containing the commit
38534d344b, so as far as 2.6.
src/hlua.c