Package: lua5.4 Version: 5.4.4-3 Severity: normal X-Debbugs-Cc: none, Asher Gordon <asd...@posteo.net>
Dear Maintainer, I found a bug in which calling lua_toclose() while the "main" stack is active (i.e., not inside a function which was called by lua_call()), can sometimes cause memory errors later. As I later found out, this was a symptom of a bug in lua_settop(). Here is a minimal example showcasing the bug:
#include <stdio.h> #include <lua.h> #include <lualib.h> #include <lauxlib.h> /* Here's where we do our experimentation. The table returned by the Lua program should be given as the sole argument on the Lua stack. */ static int experiment(lua_State *L) { /* local obj <close> = class:new() */ lua_getfield(L, -1, "new"); lua_rotate(L, -2, 1); lua_call(L, 1, 1); lua_toclose(L, -1); lua_pop(L, 1); return 0; } int main(int argc, char **argv) { lua_State *L; const char *prog; if (argc != 2) { fprintf(stderr, "Usage: %s FILE\n", argv[0]); return 1; } prog = argv[1]; L = luaL_newstate(); luaL_openlibs(L); if (luaL_loadfile(L, prog)) lua_error(L); lua_call(L, 0, 1); if (!lua_istable(L, -1)) luaL_error(L, "%s did not return a table", prog); #ifdef BAD_CODE /* Here's where the error originates! If we call experiment() manually like this, closing the value causes memory errors later on. Instead, we have to call it through Lua. */ experiment(L); #else /* This works as expected. */ lua_pushcfunction(L, experiment); lua_rotate(L, -2, 1); lua_call(L, 1, 0); #endif lua_close(L); return 0; }
local inspect = require 'inspect' local class = {} local mt = {__index = class} function mt:__close () print('Closing!') -- This triggers the error for some reason. I imagine it's not -- specific to the 'inspect' package, but rather just doing -- something complex with 'self'. print(inspect(self)) end function class:new () assert(self == mt.__index) return setmetatable({foo = 'bar'}, mt) end return class
Compile using $ gcc -Wall -O0 -DBAD_CODE `pkg-config --cflags lua5.4` -o memory-error memory-error.c `pkg-config --libs lua5.4` and then run it with $ valgrind ./memory-error test.lua You should notice many errors. If you compile without -DBAD_CODE, it works as expected (see the source for details). I tried this with the latest upstream version from git, and found that the bug did not occur. After some bisecting, I found the commit where this was fixed upstream. The commit is "196bb94d Bug: 'lua_settop' may use an invalid pointer to stack" https://github.com/lua/lua/commit/196bb94d66e727e0aec053a0276c3ad701500762 I'm not sure if this is a security issue or not. If so, please raise the Severity accordingly. I think this fix from upstream should be backported to Debian's Lua 5.4, and possibly 5.{1,2,3} as well (I haven't tested those). Hopefully it is as simple as applying the patch. Thanks, Asher -- System Information: Debian Release: trixie/sid APT prefers testing-debug APT policy: (500, 'testing-debug'), (500, 'testing') Architecture: amd64 (x86_64) Kernel: Linux 6.3.0-1-amd64 (SMP w/12 CPU threads; PREEMPT) Kernel taint flags: TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE not set Shell: /bin/sh linked to /usr/bin/dash Init: systemd (via /run/systemd/system) LSM: AppArmor: enabled Versions of packages lua5.4 depends on: ii libc6 2.37-5 ii libreadline8 8.2-1.3 lua5.4 recommends no packages. lua5.4 suggests no packages. -- no debconf information -- Yesterday upon the stair I met a man who wasn't there. He wasn't there again today -- I think he's from the CIA. -------- I prefer to send and receive mail encrypted. Please send me your public key, and if you do not have my public key, please let me know. Thanks. GPG fingerprint: 38F3 975C D173 4037 B397 8095 D4C9 C4FC 5460 8E68
signature.asc
Description: PGP signature