aboutsummaryrefslogtreecommitdiff
path: root/lapi.c
diff options
context:
space:
mode:
authorRoberto I <roberto@inf.puc-rio.br>2025-12-27 16:22:13 -0300
committerRoberto I <roberto@inf.puc-rio.br>2025-12-27 16:22:13 -0300
commit632a71b24d8661228a726deb5e1698e9638f96d8 (patch)
tree505f6df678b0d29f6924a27f4b2e285993089b5b /lapi.c
parent578ae5745cecee56d48795cd4ae1eaf13618715c (diff)
downloadlua-632a71b24d8661228a726deb5e1698e9638f96d8.tar.gz
lua-632a71b24d8661228a726deb5e1698e9638f96d8.tar.bz2
lua-632a71b24d8661228a726deb5e1698e9638f96d8.zip
BUG: Arithmetic overflow in 'collectgarbage"step"'
The computation of a new debt could overflow when we give a too large step to 'collectgarbage"step"' and the current debt was already negative. This is only an issue if your platform cares for it or if you compile Lua with an option like '-fsanitize=undefined'.
Diffstat (limited to 'lapi.c')
-rw-r--r--lapi.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/lapi.c b/lapi.c
index 42c8fcdd..9b6ca1ec 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1201,11 +1201,16 @@ LUA_API int lua_gc (lua_State *L, int what, ...) {
1201 case LUA_GCSTEP: { 1201 case LUA_GCSTEP: {
1202 lu_byte oldstp = g->gcstp; 1202 lu_byte oldstp = g->gcstp;
1203 l_mem n = cast(l_mem, va_arg(argp, size_t)); 1203 l_mem n = cast(l_mem, va_arg(argp, size_t));
1204 l_mem newdebt;
1204 int work = 0; /* true if GC did some work */ 1205 int work = 0; /* true if GC did some work */
1205 g->gcstp = 0; /* allow GC to run (other bits must be zero here) */ 1206 g->gcstp = 0; /* allow GC to run (other bits must be zero here) */
1206 if (n <= 0) 1207 if (n <= 0)
1207 n = g->GCdebt; /* force to run one basic step */ 1208 newdebt = 0; /* force to run one basic step */
1208 luaE_setdebt(g, g->GCdebt - n); 1209 else if (g->GCdebt >= n - MAX_LMEM) /* no overflow? */
1210 newdebt = g->GCdebt - n;
1211 else /* overflow */
1212 newdebt = -MAX_LMEM; /* set debt to miminum value */
1213 luaE_setdebt(g, newdebt);
1209 luaC_condGC(L, (void)0, work = 1); 1214 luaC_condGC(L, (void)0, work = 1);
1210 if (work && g->gcstate == GCSpause) /* end of cycle? */ 1215 if (work && g->gcstate == GCSpause) /* end of cycle? */
1211 res = 1; /* signal it */ 1216 res = 1; /* signal it */