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

Attachment: signature.asc
Description: PGP signature

Reply via email to