]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: lua: Use a per-thread counter to track some non-reentrant parts of lua
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 19 Mar 2021 14:16:28 +0000 (15:16 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 19 Mar 2021 15:16:23 +0000 (16:16 +0100)
Some parts of the Lua are non-reentrant. We must be sure to carefully track
these parts to not dump the lua stack when it is interrupted inside such
parts. For now, we only identified the custom lua allocator. If the thread
is interrupted during the memory allocation, we must not try to print the
lua stack wich also allocate memory. Indeed, realloc() is not
async-signal-safe.

In this patch we introduce a thread-local counter. It is incremented before
entering in a non-reentrant part and decremented when exiting. It is only
performed in hlua_alloc() for now.

include/haproxy/hlua.h
src/hlua.c

index 6aca17f39847b54b1296702e69803eabbda3d73d..36629e637028c39370ac1e0f76202485df189d88 100644 (file)
@@ -50,6 +50,7 @@ void hlua_applet_tcp_fct(struct appctx *ctx);
 void hlua_applet_http_fct(struct appctx *ctx);
 struct task *hlua_process_task(struct task *task, void *context, unsigned int state);
 
+extern THREAD_LOCAL unsigned int hlua_not_dumpable;
 #else /* USE_LUA */
 
 /************************ For use when Lua is disabled ********************/
index 42d5be2a5ade92e2ecfd79360949034222b0d786..962195a6070bbd8550e1c914cddbdc33d1a4d5da 100644 (file)
@@ -274,6 +274,9 @@ struct hlua_mem_allocator {
 
 static struct hlua_mem_allocator hlua_global_allocator THREAD_ALIGNED(64);
 
+ /* > 0 if lua is in a non-rentrant part, thus with a non-dumpable stack */
+THREAD_LOCAL unsigned int hlua_not_dumpable = 0;
+
 /* These functions converts types between HAProxy internal args or
  * sample and LUA types. Another function permits to check if the
  * LUA stack contains arguments according with an required ARG_T
@@ -8634,8 +8637,12 @@ static void *hlua_alloc(void *ud, void *ptr, size_t osize, size_t nsize)
        /* a limit of ~0 means unlimited and boot complete, so there's no need
         * for accounting anymore.
         */
-       if (likely(~zone->limit == 0))
-               return realloc(ptr, nsize);
+       if (likely(~zone->limit == 0)) {
+               hlua_not_dumpable++;
+               ptr = realloc(ptr, nsize);
+               hlua_not_dumpable--;
+               return ptr;
+       }
 
        if (!ptr)
                osize = 0;
@@ -8649,7 +8656,9 @@ static void *hlua_alloc(void *ud, void *ptr, size_t osize, size_t nsize)
                        return NULL;
        } while (!_HA_ATOMIC_CAS(&zone->allocated, &old, new));
 
+       hlua_not_dumpable++;
        ptr = realloc(ptr, nsize);
+       hlua_not_dumpable--;
 
        if (unlikely(!ptr && nsize)) // failed
                _HA_ATOMIC_SUB(&zone->allocated, nsize - osize);