]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: hlua: hook yield on known lua state
authorAurelien DARRAGON <adarragon@haproxy.com>
Fri, 7 Apr 2023 14:34:20 +0000 (16:34 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 19 Apr 2023 09:03:31 +0000 (11:03 +0200)
When forcing a yield attempt from hlua_hook(), we should perform it on
the known hlua state, not on a potential substate created using
coroutine.create() from an existing hlua state from lua script.

Indeed, only true hlua couroutines will properly handle the yield and
perform the required timeout checks when returning in hlua_ctx_resume().

So far, this was not a concern because hlua_gethlua() would return NULL
if hlua_hook() is not directly being called from a hlua coroutine anyway.

But with this we're trying to make hlua_hook() ready for being called
from a subcoroutine which inherits from a parent hlua ctx.
In this case, no yield attempt will be performed, we will simply check
for hlua timeouts.

Not doing so would result in the timeout checks not being performed since
hlua_ctx_resume() is completely bypassed when yielding from the subroutine,
resulting in a user-defined coroutine potentially going rogue unnoticed.

src/hlua.c

index 356c04c1b4d34c35613d3a194e5c4b38c1466c90..8f562718f1a5d394434ddf64d0ea6754279950fd 100644 (file)
@@ -1562,6 +1562,18 @@ void hlua_hook(lua_State *L, lua_Debug *ar)
        if (!hlua)
                return;
 
+       if (hlua->T != L) {
+               /* We don't want to enforce a yield on a sub coroutine, since
+                * we have no guarantees that the yield will be handled properly.
+                * Indeed, only the hlua->T coroutine is being handled through
+                * hlua_ctx_resume() function.
+                *
+                * Instead, we simply check for timeouts and wait for the sub
+                * coroutine to finish..
+                */
+               goto check_timeout;
+       }
+
        /* Lua cannot yield when its returning from a function,
         * so, we can fix the interrupt hook to 1 instruction,
         * expecting that the function is finished.
@@ -1596,6 +1608,7 @@ void hlua_hook(lua_State *L, lua_Debug *ar)
                return;
        }
 
+ check_timeout:
        /* If we cannot yield, check the timeout. */
        if (!hlua_timer_check(&hlua->timer)) {
                lua_pushfstring(L, "execution timeout");