lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


While I obviously dont speak for the 'lua gods', the general design of lua is one where cleanliness and speed are valued over 'protection' -- if you trust your environment/users enough to leave binary loadstring available, then you also implictly trust them not to feed you invalid bytecode. You could of course add your own verifier that scans the bytecode to ensure that it's well-formed, but that kind of overhead feels like it may be a deliberate omission, rather than a bug.

Having said all that, I haven't figured out how hard a well-formedness test would be for lua bytecode, so it might be something that has a negligible runtime overhead for a considerable stability pay-off.

Daniel.

Peter Cawley wrote:
Consider the following code:

s = string.dump(function() return end)
pre, post = s:find(string.char(30, 0, 128, 0), 1, true)
assert(loadstring(s:sub(1, pre - 1) .. string.char(34, 0, 0, 0) ..
s:sub(post + 1, -1)))()

When run, it can cause the Lua interpreter to crash. First it creates
a function whose opcodes are:
RETURN
RETURN

Then it dumps this to a string and replaces the first RETURN with a
SETLIST, loads this modified chunk and executes it. The Lua VM
executes the SETLIST instruction, and as C is 0, it skips the next
instruction and uses it as a list offset. The VM now continues to
execute whatever came after the final RETURN, which will be whatever
is in memory after the end of the instruction array. Worst case is
that these instructions cause a segfault, best case is a runtime
error.

Potential fix would be to add the following line to the precheck
function in ldebug.c:
if(pt->sizecode > 1) check(GET_OPCODE(pt->code[pt->sizecode-2]) != OP_SETLIST);