Skip to content

v4.0.2

Latest

Choose a tag to compare

@doracawl doracawl released this 04 Oct 06:54
· 1172 commits to develop since this release

No breaking change. One memory-safety fix in the trace JIT. With the JIT on, a recursive function that called a value held in an upvalue could crash the process; --no-jit was not affected.

  • A table with __call, or a native function, called through an upvalue from a recursive function was typed by the trace as a Lua function without a check. When the trace left at that call, the value was written back as a Lua function and the interpreter ran it as one: a segmentation fault in release builds, a heap-buffer-overflow under AddressSanitizer. A ten-line script triggered it with the default JIT settings in every dialect, 5.1 through 5.5:

    local hits = 0
    local MT = {}
    MT.__call = function(_, y) hits = hits + 1 return (tonumber(y) or 0) + 1 end
    local M = setmetatable({}, MT)
    local function rec(r, acc)
      if r <= 0 then return acc end
      return rec(r - 1, acc) + ((M(0.5)) + 92)
    end
    for i = 1, 2000 do rec(1, 0) end
    print(hits)

    local f = math.abs in place of M crashed the same way. The trace now checks the value where it reads it, and leaves to the interpreter when it is not a Lua function.

  • Affected versions: from 1.1.0 on may be affected; 2.18.0 through 4.0.1 are confirmed. Upgrading is recommended for anyone running untrusted or varied Lua code with the JIT on.

See CHANGELOG.md.