mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-04-02 05:10:42 +02:00
lua: force text mode for loading plugins
luaL_loadfile() by default allows for both text files and precompiled lua files. Precompiled files are not verified on load allowing for a sandbox escape. CVE-2026-35093 Fixes: #1271 Found-by: Koen Tange <koen@monokles.eu> Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1459>
This commit is contained in:
parent
45dfd0f030
commit
356c498fd4
2 changed files with 70 additions and 1 deletions
|
|
@ -1362,7 +1362,7 @@ libinput_lua_plugin_new_from_path(struct libinput *libinput, const char *path)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int ret = luaL_loadfile(L, path);
|
||||
int ret = luaL_loadfilex(L, path, "t");
|
||||
if (ret == LUA_OK) {
|
||||
plugin->L = steal(&L);
|
||||
|
||||
|
|
|
|||
|
|
@ -1204,10 +1204,79 @@ START_TEST(lua_remove_plugin_on_timeout)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
/* Pre-compiled Lua 5.4 bytecode for the following source:
|
||||
*
|
||||
* libinput:register({1})
|
||||
* libinput:connect("new-evdev-device", function(device)
|
||||
* libinput:log_info("loaded from binary lua file")
|
||||
* end)
|
||||
*
|
||||
* To regenerate:
|
||||
* luac5.4 -o /dev/stdout /tmp/plugin.lua | xxd -i
|
||||
*/
|
||||
static const unsigned char binary_lua_plugin[] = {
|
||||
0x1b, 0x4c, 0x75, 0x61, 0x54, 0x00, 0x19, 0x93, 0x0d, 0x0a, 0x1a, 0x0a, 0x04,
|
||||
0x08, 0x08, 0x78, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x28, 0x77, 0x40, 0x01, 0x9b, 0x40, 0x74, 0x65, 0x73, 0x74, 0x2f,
|
||||
0x31, 0x30, 0x2d, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x2d, 0x70, 0x6c, 0x75,
|
||||
0x67, 0x69, 0x6e, 0x2e, 0x6c, 0x75, 0x61, 0x80, 0x80, 0x00, 0x01, 0x04, 0x8e,
|
||||
0x51, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x14, 0x80, 0x00, 0x01, 0x13,
|
||||
0x01, 0x00, 0x01, 0x52, 0x00, 0x00, 0x00, 0x81, 0x01, 0x00, 0x80, 0x4e, 0x01,
|
||||
0x01, 0x00, 0x44, 0x00, 0x03, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x14, 0x80, 0x00,
|
||||
0x02, 0x03, 0x81, 0x01, 0x00, 0xcf, 0x01, 0x00, 0x00, 0x44, 0x00, 0x04, 0x01,
|
||||
0x46, 0x00, 0x01, 0x01, 0x84, 0x04, 0x89, 0x6c, 0x69, 0x62, 0x69, 0x6e, 0x70,
|
||||
0x75, 0x74, 0x04, 0x89, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x04,
|
||||
0x88, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x04, 0x91, 0x6e, 0x65, 0x77,
|
||||
0x2d, 0x65, 0x76, 0x64, 0x65, 0x76, 0x2d, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65,
|
||||
0x81, 0x01, 0x00, 0x00, 0x81, 0x80, 0x8d, 0x8f, 0x01, 0x00, 0x04, 0x85, 0x8b,
|
||||
0x00, 0x00, 0x00, 0x94, 0x80, 0x01, 0x01, 0x83, 0x01, 0x01, 0x00, 0xc4, 0x00,
|
||||
0x03, 0x01, 0xc7, 0x00, 0x01, 0x00, 0x83, 0x04, 0x89, 0x6c, 0x69, 0x62, 0x69,
|
||||
0x6e, 0x70, 0x75, 0x74, 0x04, 0x89, 0x6c, 0x6f, 0x67, 0x5f, 0x69, 0x6e, 0x66,
|
||||
0x6f, 0x04, 0x9c, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x20, 0x66, 0x72, 0x6f,
|
||||
0x6d, 0x20, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x20, 0x6c, 0x75, 0x61, 0x20,
|
||||
0x66, 0x69, 0x6c, 0x65, 0x81, 0x00, 0x00, 0x00, 0x80, 0x85, 0x01, 0x00, 0x00,
|
||||
0x00, 0x01, 0x80, 0x81, 0x87, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x80, 0x85,
|
||||
0x81, 0x85, 0x5f, 0x45, 0x4e, 0x56, 0x8e, 0x01, 0x0b, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0xfe, 0x02, 0x80, 0x80, 0x81, 0x85, 0x5f,
|
||||
0x45, 0x4e, 0x56,
|
||||
};
|
||||
|
||||
START_TEST(lua_reject_precompiled_files)
|
||||
{
|
||||
_destroy_(tmpdir) *tmpdir = tmpdir_create(NULL);
|
||||
|
||||
/* Write the binary bytecode to a .lua file in the tmpdir.
|
||||
* Binary (pre-compiled) Lua files must be rejected by the
|
||||
* plugin loader for security reasons. */
|
||||
_autofree_ char *path = strdup_printf("%s/10-binary-plugin.lua", tmpdir->path);
|
||||
_autoclose_ int fd = open(path, O_WRONLY | O_CREAT, 0644);
|
||||
litest_assert_errno_success(fd);
|
||||
|
||||
ssize_t written = write(fd, binary_lua_plugin, sizeof(binary_lua_plugin));
|
||||
litest_assert_int_eq((int)written, (int)sizeof(binary_lua_plugin));
|
||||
fsync(fd);
|
||||
|
||||
_litest_context_destroy_ struct libinput *li =
|
||||
litest_create_context_with_plugindir(tmpdir->path);
|
||||
|
||||
litest_with_logcapture(li, capture) {
|
||||
libinput_plugin_system_load_plugins(li,
|
||||
LIBINPUT_PLUGIN_SYSTEM_FLAG_NONE);
|
||||
litest_drain_events(li);
|
||||
|
||||
size_t index = 0;
|
||||
litest_assert(
|
||||
strv_find_substring(capture->errors, "Failed to load", &index));
|
||||
litest_assert_str_in(path, capture->errors[index]);
|
||||
}
|
||||
}
|
||||
END_TEST
|
||||
|
||||
TEST_COLLECTION(lua)
|
||||
{
|
||||
/* clang-format off */
|
||||
litest_add_no_device(lua_load_failure);
|
||||
litest_add_no_device(lua_reject_precompiled_files);
|
||||
litest_with_parameters(params,
|
||||
"content", 'I', 6,
|
||||
litest_named_i32(EMPTY),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue