Current aarch64 (distro) kernels ship with CONFIG_ARM64_VA_BITS_48
enabled, see, e.g., [1] for Debian's kernel, resulting in a LuaJIT
panic "bad light userdata pointer" on aarch64 with distro-packaged
old(er) LuaJIT versions that limit lightuserdata to 47 bit pointers.
One mitigation option is to use a kernel with less VA bits, ruling
out using distro kernels untouched.
Another mitigation is to use the latest LuaJIT as this issue has
been resolved, see [2,3], ruling out using the (older) distro's
LuaJIT package untouched -- until distros eventually catch up.
Hence, to allow SWUpdate on systems with >47 bits VA to run on current
distros' kernel and LuaJIT packages, replace lightuserdata with "full"
userdata. For other systems with with <=47 bits VA, this change has no
effect other than Lua's gc having to clean up the "full" userdata of
sizeof(struct dict*) when it becomes unreferenced:
For sw-description embedded scripts, this is happens after having
interpreted sw-description.
For a Lua handler, this happens at its next call as an explicit free
and gc cycle call would occupy more permanent space.
[1]
https://salsa.debian.org/kernel-team/linux/-/blob/bullseye/debian/config/arm64/config#L13
[2]
https://github.com/LuaJIT/LuaJIT/issues/49
[3]
https://github.com/LuaJIT/LuaJIT/pull/230
Signed-off-by: Christian Storm <
christi...@siemens.com>
Signed-off-by: Michael Adler <
michae...@siemens.com>
---
corelib/lua_interface.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/corelib/lua_interface.c b/corelib/lua_interface.c
index a6da6f2..e1a9c3e 100644
--- a/corelib/lua_interface.c
+++ b/corelib/lua_interface.c
@@ -854,7 +854,7 @@ static int l_get_bootenv(lua_State *L) {
}
static int l_set_bootenv(lua_State *L) {
- struct dict *bootenv = (struct dict *)lua_touserdata(L, lua_upvalueindex(1));
+ struct dict *bootenv = *(struct dict**)lua_touserdata(L, lua_upvalueindex(1));
const char *name = luaL_checkstring(L, 1);
const char *value = luaL_checkstring(L, 2);
@@ -1036,7 +1036,8 @@ static int l_handler_wrapper(struct img_type *img, void *data) {
ERROR("Lua stack corrupted.");
return -1;
}
- lua_pushlightuserdata(gL, (void *)img->bootloader);
+ struct dict **udbootenv = lua_newuserdata(gL, sizeof(struct dict*));
+ *udbootenv = img->bootloader;
luaL_setfuncs(gL, l_swupdate_bootenv, 1);
lua_pop(gL, 1);
}
@@ -1206,7 +1207,8 @@ lua_State *lua_parser_init(const char *buf, struct dict *bootenv)
lua_setglobal(L, "SWUPDATE_LUA_TYPE"); /* prime L as LUA_TYPE_PEMBSCR */
luaL_openlibs(L); /* opens the standard libraries */
luaL_requiref(L, "swupdate", luaopen_swupdate, 1 );
- lua_pushlightuserdata(L, (void *)bootenv);
+ struct dict **udbootenv = lua_newuserdata(L, sizeof(struct dict*));
+ *udbootenv = bootenv;
luaL_setfuncs(L, l_swupdate_bootenv, 1);
lua_pop(L, 1); /* remove unused copy left on stack */
--
2.33.0