Hi Moritz, On Tue, 25 Apr 2023 at 20:58:00 +0200, Moritz Mühlenhoff wrote: > CVE-2021-43519[0]: > | Stack overflow in lua_resume of ldo.c in Lua Interpreter 5.1.0~5.4.4 > | allows attackers to perform a Denial of Service via a crafted script > | file.
While trigaging this for LTS I was unable to trigger the crash with lua5.1, lua5.2, or lua5.3 on buster, bullseye, or bookworm. AFAICT only bullseye's lua5.4 is affected: buster ====== $ lua5.1 ./cstack.lua testing stack overflow detection nesting coroutines running after recoverable errors final count: 198 $ lua5.2 ./cstack.lua testing stack overflow detection nesting coroutines running after recoverable errors final count: 197 $ lua5.3 ./cstack.lua testing stack overflow detection nesting coroutines running after recoverable errors final count: 197 bullseye ======== $ lua5.1 ./cstack.lua testing stack overflow detection nesting coroutines running after recoverable errors final count: 198 $ lua5.2 ./cstack.lua testing stack overflow detection nesting coroutines running after recoverable errors final count: 197 $ lua5.3 ./cstack.lua testing stack overflow detection nesting coroutines running after recoverable errors final count: 197 $ lua5.4 ./cstack.lua testing stack overflow detection nesting coroutines running after recoverable errors E: Child terminated by signal ‘Segmentation fault’ bookworm ======== $ lua5.1 ./cstack.lua testing stack overflow detection nesting coroutines running after recoverable errors final count: 198 $ lua5.2 ./cstack.lua testing stack overflow detection nesting coroutines running after recoverable errors final count: 197 $ lua5.3 ./cstack.lua testing stack overflow detection nesting coroutines running after recoverable errors final count: 197 $ lua5.4 ./cstack.lua testing stack overflow detection nesting coroutines running after recoverable errors final count: 197 As the reporter suggested at http://lua-users.org/lists/lua-l/2021-10/msg00123.html, the issue is that L->nCcalls is incremented in resume(), but that function is called via luaD_rawrunprotected() which resets the state on error: https://sources.debian.org/src/lua5.4/5.4.2-2/src/ldo.c/#L716 . AFAICT lua5.3 is unaffected since there L->nCcalls is incremented in lua_resume() i.e., outside LUAI_THROW: https://sources.debian.org/src/lua5.3/5.3.3-1.1/src/ldo.c/#L659 Didn't try to bisect but I believe this was introduced upstream at https://github.com/lua/lua/commit/287b302acb8d925178e9edb800f0a8d18c7d35f6#diff-a1e6f0be3689739fa1e5707427e78d792c7f6a333bed95fd05c4382d60bda7c4L687-R689 Cheers, -- Guilhem.
-- $Id: testes/cstack.lua $ -- See Copyright Notice in file all.lua local tracegc = require"tracegc" print"testing stack overflow detection" local function checkerror (msg, f, ...) local s, err = pcall(f, ...) assert(not s and string.find(err, msg)) end do -- bug in 5.4.2 print("nesting coroutines running after recoverable errors") local count = 0 local function foo() count = count + 1 pcall(1) -- create an error -- running now inside 'precover' ("protected recover") coroutine.wrap(foo)() -- call another coroutine end checkerror("C stack overflow", foo) print("final count: ", count) end
-- track collections local M = {} -- import list local setmetatable, stderr, collectgarbage = setmetatable, io.stderr, collectgarbage _ENV = nil local active = false -- each time a table is collected, remark it for finalization on next -- cycle local mt = {} function mt.__gc (o) stderr:write'.' -- mark progress if active then setmetatable(o, mt) -- remark object for finalization end end function M.start () if not active then active = true setmetatable({}, mt) -- create initial object end end function M.stop () if active then active = false collectgarbage() -- call finalizer for the last time end end return M
signature.asc
Description: PGP signature