[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Bytecode abuse in Lua 5.2 (-work4)
- From: Peter Cawley <lua@...>
- Date: Sun, 22 Aug 2010 12:49:02 +0100
On Sun, Aug 22, 2010 at 12:17 PM, KHMan <keinhong@gmail.com> wrote:
> On 8/22/2010 7:05 PM, Martin Guy wrote:
>>>>>>>
>>>>>>> Very informative, thanks! :o
>>>>>>
>>>>>> Was this really worth posting to the entire list?
>>>>>
>>>>> Your comment was made because you're not interested in the subject or
>>>>> because you prefer security through obscurity? Or for some other
>>>
>>> reason?
>>>>
>>>> I read it as in response to Majic, personally...
>>>
>>> Now, I'm embarrassed. I see Majic's comment now, and I can see why
>>> Martin
>>> made the comment.
>>
>> [snip]
>> With Lua being embedded in every conceivable program, browser, photo
>> editor and web game, a security hole like this would be about as much
>> fun as the eternal security holes in flash player. A wise response
>> from the Lua dev community would be to reinstate the bytecode sanity
>> checking by default, and if removing it has significant advantages
>> (code size, speed) allowing it to be disabled only #ifdef
>> FAST_AND_FURIOUS
>
> "reinstate the bytecode sanity checking by default"?
>
> No you got it all wrong, the point is, there is currently no bulletproof
> bytecode checker, hence the old one has been withdrawn. It is vulnerable, as
> amply demonstrated.
While that is true, there are reasons why the module (as it currently
stands) will not work in Lua 5.1:
1) Most importantly, 5.1's SETLIST instruction checks at runtime that
the specified table is actually a table. This check is very cheap, and
has to be done at runtime rather than load-time, but can only fail for
maliciously crafted bytecode (or specially crafted usage of
debug.sethook and debug.setlocal, but the dangers of these should
already be known). If this check was reinstated, then my module would
all stop working (as can be seen from my diagram, all reads/writes
depend on write_tvalue, which in turn depends on setlist_fn).
2) 5.2's auxiliary library buffer system uses userdata rather than
5.1's concatenation tower. Combined with the lowcall bytecode abuse,
this provides us with a simple way of getting a mutable block of
memory of specified size and initial contents, and also obtaining a
string representation of the "final" contents of the mutable block.
Doing something similar in 5.1 would be harder, though perhaps not
impossible.
3) 5.1's coroutine.running doesn't always return a coroutine, whereas
5.2's does. Given that my module just needs any coroutine, the call to
coroutine.running would have to be replaced with one to
coroutine.create (though only write_memory needs a coroutine to
inspect, the other functions work fine without the coroutine library).