Package: lua5.4
Version: 5.4.4-3
Severity: normal
X-Debbugs-Cc: none, Asher Gordon
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
#include
#include
#include
/* 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 = 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