]> git.ipfire.org Git - thirdparty/haproxy.git/commit
BUG/MEDIUM: lua: defer Lua VM initialisation to the first Lua config keyword
authorWilliam Lallemand <wlallemand@irq6.net>
Wed, 27 May 2026 17:54:48 +0000 (19:54 +0200)
committerWilliam Lallemand <wlallemand@haproxy.com>
Thu, 28 May 2026 09:36:02 +0000 (11:36 +0200)
commit1c59c39171529b5c6bb7e661e2bcbc933747f65b
tree3b574e3e69a4af4ec95a3b6320356c0f43f977ea
parent9a39e55dedbfbd299a01d2af65a37b491a77ab0b
BUG/MEDIUM: lua: defer Lua VM initialisation to the first Lua config keyword

HAProxy used to call hlua_init() unconditionally from step_init_1(),
before any configuration file was parsed.  As a consequence, Lua states
0 and 1 were always created with hlua_openlibs_flags set to its default
value (HLUA_OPENLIBS_ALL), regardless of any tune.lua.openlibs directive
that appeared later in the global section.  With multiple threads, states
2..N were created correctly in hlua_post_init() after the config had been
parsed, while states 0 and 1 retained the full standard-library set.
This produced the observable bug reported in GitHub issue #3396: a script
loaded with lua-load-per-thread could see require() as a function on
thread 1 but nil on thread 2 when tune.lua.openlibs was used to restrict
the available libraries.

The initialisation is now lazy.  hlua_init() is idempotent: it returns
immediately if the states already exist (hlua_states[0] != NULL).  It is
called explicitly from the three config keyword handlers that need the
Lua states to be live before they can do their work (lua-load,
lua-load-per-thread, lua-prepend-path) and from tune.lua.openlibs, after
the hlua_openlibs_flags variable has been updated, so that the states are
always created with the correct library set.

hlua_post_init() calls hlua_init() unconditionally as a safety net,
covering the case where no Lua directive appeared in the configuration at
all (no global section, or only pure-tuning directives such as timeouts
and memory limits), and ensuring correct behaviour with multiple
consecutive global sections.

As a result of this change, tune.lua.openlibs must now appear before
lua-load, lua-load-per-thread, and lua-prepend-path in the configuration;
if any of those keywords is encountered first, the Lua states will already
be initialised and tune.lua.openlibs with a non-default value will return
a parse error.

No backport needed.
doc/configuration.txt
src/haproxy.c
src/hlua.c