future of bytecode verifier

classic Classic list List threaded Threaded
46 messages Options
123
Reply | Threaded
Open this post in threaded view
|

future of bytecode verifier

Luiz Henrique de Figueiredo
Following several bytecode exploits found by the relentless Peter Cawley
and others, we are considering dropping the bytecode verifier completely in
Lua 5.2. It seems useless to make a promise that we can't seem to deliver
without a much more complicated verifier than the current one, and possibly
with the need for costly runtime checks as well.

Our impression is that applications that are open to running arbitrary Lua
code provided by the user should avoid accepting precompiled scripts. So we
think that adding a flag to load (the Lua function from the base library)
to check for and reject precompiled scripts is enough for Lua-based apps
to be able to reject precompiled scripts if they want to. We don't think
anything else is needed in the C side, since you can always write you own
lua_Reader function to reject precompiled scripts.

At the same time, shedding the bytecode verifier would allow applications
that run their own precompiled scripts that are deemed safe to avoid the
cost of the bytecode verifier. The checks would be limited to the sanity
tests done in lundump.c, which should be enough for flagging accidental
file corruption.

All feedback is welcome.  Thanks.
--lhf

Reply | Threaded
Open this post in threaded view
|

Re: future of bytecode verifier

David Jones-2

On 4 Mar 2009, at 18:58, Luiz Henrique de Figueiredo wrote:

Following several bytecode exploits found by the relentless Peter Cawley and others, we are considering dropping the bytecode verifier completely in Lua 5.2. It seems useless to make a promise that we can't seem to deliver without a much more complicated verifier than the current one, and possibly
with the need for costly runtime checks as well.

A bold move that sheds a load of code.  I like it.

drj

Reply | Threaded
Open this post in threaded view
|

Re: future of bytecode verifier

Gabríel "A." Pétursson
In reply to this post by Luiz Henrique de Figueiredo
I'd suggest making the current byte-code verifier optional in luaconf.h.

On Wed, 2009-03-04 at 15:58 -0300, Luiz Henrique de Figueiredo wrote:
> Following several bytecode exploits found by the relentless Peter Cawley
> and others, we are considering dropping the bytecode verifier completely in
> Lua 5.2. It seems useless to make a promise that we can't seem to deliver
> without a much more complicated verifier than the current one, and possibly
> with the need for costly runtime checks as well.
> 
> Our impression is that applications that are open to running arbitrary Lua
> code provided by the user should avoid accepting precompiled scripts. So we
> think that adding a flag to load (the Lua function from the base library)
> to check for and reject precompiled scripts is enough for Lua-based apps
> to be able to reject precompiled scripts if they want to. We don't think
> anything else is needed in the C side, since you can always write you own
> lua_Reader function to reject precompiled scripts.
> 
> At the same time, shedding the bytecode verifier would allow applications
> that run their own precompiled scripts that are deemed safe to avoid the
> cost of the bytecode verifier. The checks would be limited to the sanity
> tests done in lundump.c, which should be enough for flagging accidental
> file corruption.
> 
> All feedback is welcome.  Thanks.
> --lhf


Reply | Threaded
Open this post in threaded view
|

Re: future of bytecode verifier

Thomas Harning Jr.
On Mar 4, 2009, at 3:02 PM, Gabríel A. Pétursson wrote:
I'd suggest making the current byte-code verifier optional in luaconf.h.


If possible, pulling the bytecode verifier to an external library would be useful... that way it could be optional. If still packaged with Lua (preferably its own file to keep things clean) then the luaconf.h configuration could enable it and buffer loading could invoke the verifier.

I suppose the trick would be to be able to yank it out in a usable manner, since I suspect that bytecode verification relies strongly on its parsed version.

Reply | Threaded
Open this post in threaded view
|

Re: future of bytecode verifier

Luiz Henrique de Figueiredo
> If possible, pulling the bytecode verifier to an external library  
> would be useful... that way it could be optional.

The whole point is that providing a bytecode verifier that is flawed 
(even if it's only in malicious code) gives you an illusion of safety.
And this is as bad, or actually worse, than having no verifier.

Reply | Threaded
Open this post in threaded view
|

Re: future of bytecode verifier

Alexander Gladysh
In reply to this post by Luiz Henrique de Figueiredo
On Wed, Mar 4, 2009 at 9:58 PM, Luiz Henrique de Figueiredo
<[hidden email]> wrote:
> Following several bytecode exploits found by the relentless Peter Cawley
> and others, we are considering dropping the bytecode verifier completely in
> Lua 5.2. It seems useless to make a promise that we can't seem to deliver
> without a much more complicated verifier than the current one, and possibly
> with the need for costly runtime checks as well.

I agree.

> Our impression is that applications that are open to running arbitrary Lua
> code provided by the user should avoid accepting precompiled scripts. So we
> think that adding a flag to load (the Lua function from the base library)
> to check for and reject precompiled scripts is enough for Lua-based apps
> to be able to reject precompiled scripts if they want to. We don't think
> anything else is needed in the C side, since you can always write you own
> lua_Reader function to reject precompiled scripts.

Perhaps a luaL_* convenience function?

Alexander.

rui
Reply | Threaded
Open this post in threaded view
|

Re: future of bytecode verifier

rui
I guess the point is: Why have a verifier if it is flawed ?

IÂm quite new here, so sorry for the intrusion, but i vote to be
removed. Less code, better to Lua :).

rui.




On Wed, Mar 4, 2009 at 5:36 PM, Alexander Gladysh <[hidden email]> wrote:
> On Wed, Mar 4, 2009 at 9:58 PM, Luiz Henrique de Figueiredo
> <[hidden email]> wrote:
>> Following several bytecode exploits found by the relentless Peter Cawley
>> and others, we are considering dropping the bytecode verifier completely in
>> Lua 5.2. It seems useless to make a promise that we can't seem to deliver
>> without a much more complicated verifier than the current one, and possibly
>> with the need for costly runtime checks as well.
>
> I agree.
>
>> Our impression is that applications that are open to running arbitrary Lua
>> code provided by the user should avoid accepting precompiled scripts. So we
>> think that adding a flag to load (the Lua function from the base library)
>> to check for and reject precompiled scripts is enough for Lua-based apps
>> to be able to reject precompiled scripts if they want to. We don't think
>> anything else is needed in the C side, since you can always write you own
>> lua_Reader function to reject precompiled scripts.
>
> Perhaps a luaL_* convenience function?
>
> Alexander.
>


Reply | Threaded
Open this post in threaded view
|

Re: future of bytecode verifier

Jorge Visca
In reply to this post by Luiz Henrique de Figueiredo
On Wed, 2009-03-04 at 17:21 -0300, Luiz Henrique de Figueiredo wrote:
> The whole point is that providing a bytecode verifier that is flawed 
> (even if it's only in malicious code) gives you an illusion of safety.
> And this is as bad, or actually worse, than having no verifier.

I say, stuck all that code in a module where it can peacefully grow to a
Turing-defeating AI the size of Windows Vista.


Reply | Threaded
Open this post in threaded view
|

Re: future of bytecode verifier

Ralph Hempel
In reply to this post by Luiz Henrique de Figueiredo
If you cannot guarantee that the verifier works in
all cases, then I agree that having it gives a false sense
of security.

As I'm very interested in reducing the size of my firmware
image, what function names are affected?

Ralph

Reply | Threaded
Open this post in threaded view
|

Re: future of bytecode verifier

Florian Weimer
In reply to this post by Luiz Henrique de Figueiredo
* Luiz Henrique de Figueiredo:

> The whole point is that providing a bytecode verifier that is flawed 
> (even if it's only in malicious code) gives you an illusion of safety.
> And this is as bad, or actually worse, than having no verifier.

You might also have to deal with PR fallout due to people disclosing
security vulnerabilities in the verifier, no matter how irrelevant
they are in practice.

Reply | Threaded
Open this post in threaded view
|

Re: future of bytecode verifier

Sam Roberts
In reply to this post by Luiz Henrique de Figueiredo
On Wed, Mar 4, 2009 at 10:58 AM, Luiz Henrique de Figueiredo
<[hidden email]> wrote:
> Following several bytecode exploits found by the relentless Peter Cawley
> and others, we are considering dropping the bytecode verifier completely in
> Lua 5.2.

I'm also OK with dropping the verifier.

What does Peter think? I've been curious for a while what he is doing
that has resulted in him finding all these issues!

Cheers,
Sam

Reply | Threaded
Open this post in threaded view
|

Re: future of bytecode verifier

Peter Cawley
On Wed, Mar 4, 2009 at 10:07 PM, Sam Roberts <[hidden email]> wrote:
> What does Peter think? I've been curious for a while what he is doing
> that has resulted in him finding all these issues!

I just like to find out how things work and then try to break them - I
don't have any project in development which involves Lua bytecode.
Being a pre-university student, I have plenty of free time to spend
messing around with code and occasionally find things like these.

Reply | Threaded
Open this post in threaded view
|

RE: future of bytecode verifier

Ian Bevan
-----Original Message-----
From: [hidden email]
[[hidden email]] On Behalf Of Peter Cawley
Sent: Thursday, 5 March 2009 12:44 p.m.
To: Lua list
Subject: Re: future of bytecode verifier

On Wed, Mar 4, 2009 at 10:07 PM, Sam Roberts <[hidden email]>
wrote:
> What does Peter think? I've been curious for a while what he is doing
> that has resulted in him finding all these issues!

> I just like to find out how things work and then try to break them - I
> don't have any project in development which involves Lua bytecode.


> Being a pre-university student, I have plenty of free time to spend
> messing around with code and occasionally find things like these.

And all around the world, middle aged software developers with families,
kids and deadlines look on jealously and wonder what happened to the
last 20 years of their lives... 

Or maybe just me?

:)


Reply | Threaded
Open this post in threaded view
|

Re: future of bytecode verifier

Dirk Feytons
In reply to this post by Ralph Hempel
On Wed, Mar 4, 2009 at 10:50 PM, Ralph Hempel
<[hidden email]> wrote:
> If you cannot guarantee that the verifier works in
> all cases, then I agree that having it gives a false sense
> of security.
>
> As I'm very interested in reducing the size of my firmware
> image, what function names are affected?

I'm interested as well.

Lhf, you mentioned the cost of the verifier; do you have any concrete numbers?

Could the current verifier be transformed to a lua_Reader example that
is distributed separately in ./etc (like all.c/min.c/noparser.c)?

-- 
Dirk

Reply | Threaded
Open this post in threaded view
|

Re: future of bytecode verifier

peterhickman
In reply to this post by Jorge Visca

On 4 Mar 2009, at 21:46, Jorge wrote:

I say, stuck all that code in a module where it can peacefully grow to a
Turing-defeating AI the size of Windows Vista.


That's the thing though (Vista joke aside), who is going to develop the verifier given that the current one does not work?


Reply | Threaded
Open this post in threaded view
|

Re: future of bytecode verifier

Luiz Henrique de Figueiredo
In reply to this post by Dirk Feytons
> what function names are affected?

In debug.c, see "Symbolic Execution and code checker". Then I guess
remove everything that has "check" in its name, leaving a lean symbexec
that is still needed for error reporting.

> you mentioned the cost of the verifier; do you have any concrete numbers?

Not officially, but I followed my "instructions" above and it'd be
around 150 less lines in ldebug.c, which translate to around 1.5k of
code. I don't have numbers for execution time, though.

The main cost is not space or time, but the conceptual cost of having and
maintaining a verifier that does not work in all cases.

> Could the current verifier be transformed to a lua_Reader example that
> is distributed separately in ./etc (like all.c/min.c/noparser.c)?

No. First, it's pointless to have a flawed verifier. Second, the verifier
works on the bytecode and so making it a lua_Reader would imply replicating
most if not all of lundump.c.

Reply | Threaded
Open this post in threaded view
|

RE: future of bytecode verifier

John Hind
In reply to this post by Luiz Henrique de Figueiredo
I agree strongly that the safety case for bytecode (that term grates with
me, but I'll stick with it this time) should be that the writer is
responsible for verification. But if this is done, I think the route for
bytecode reading should be fully separated from the "normal" route for Lua
source. There should be a different API function, a different Lua library
function and crucially a different lua_Reader (which would be a stub
implementation by default, as would be lua_Writer).

This approach makes Lua "safe by default" and anyone implementing bytecode
support is made responsible for the integrity of the bytecodes between write
and read operations (for example by restricting to a protected store, or
even by implementing cryptographic signing).

Can I also request that consideration be given to sorting out the
"endedness" problem for Lua bytecode? Either pick an endedness for the saved
format and convert if necessary on both write and read, or if this is
thought inefficient, have a flag for the endedness in the format and convert
on read if necessary. One of the benefits of bytecode should be full support
for heterogeneous computing platforms, and Lua does this now except for this
one little wrinkle (which, of course, makes it even more misleading to call
it "bytecode").

-----Original Message-----
From: Luiz Henrique de Figueiredo Sent: 04 March 2009 18:58

Following several bytecode exploits found by the relentless Peter Cawley
and others, we are considering dropping the bytecode verifier completely in
Lua 5.2. It seems useless to make a promise that we can't seem to deliver
without a much more complicated verifier than the current one, and possibly
with the need for costly runtime checks as well.

Our impression is that applications that are open to running arbitrary Lua
code provided by the user should avoid accepting precompiled scripts. So we
think that adding a flag to load (the Lua function from the base library)
to check for and reject precompiled scripts is enough for Lua-based apps
to be able to reject precompiled scripts if they want to. We don't think
anything else is needed in the C side, since you can always write you own
lua_Reader function to reject precompiled scripts.

At the same time, shedding the bytecode verifier would allow applications
that run their own precompiled scripts that are deemed safe to avoid the
cost of the bytecode verifier. The checks would be limited to the sanity
tests done in lundump.c, which should be enough for flagging accidental
file corruption.

All feedback is welcome.  Thanks.
--lhf

Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply | Threaded
Open this post in threaded view
|

Re: future of bytecode verifier

Luiz Henrique de Figueiredo
> This approach makes Lua "safe by default" and anyone implementing bytecode
> support is made responsible for the integrity of the bytecodes between write
> and read operations (for example by restricting to a protected store, or
> even by implementing cryptographic signing).

This would break existing programs, though. And it'd be policy not mechanisms,
while Lua goes for the oposite.
 
> Can I also request that consideration be given to sorting out the
> "endedness" problem for Lua bytecode?

As discussed before, the portability issues in the bytecode format are not
restricted to endianness. I've also explained here that it's simple to write
your own bytecode format -- you just have to edit ldump.c and lundump.c,
and just the low-level functions.

> have a flag for the endedness in the format

It's there already.

> One of the benefits of bytecode should be full support for
> heterogeneous computing platforms

The one really portable Lua format is source. Really. The parser is very
fast as it is. But I see your point, of course.

Reply | Threaded
Open this post in threaded view
|

RE: future of bytecode verifier

John Hind
OK, but I do not think the proposed mechanism is optimal, at the 'C' level.
Firstly the lua_Reader function replacement has to process the internals of
the bytecode format thus breaking containment, and secondly it still has to
pass the data on through a channel which is *capable* of bypassing the
parser opening an unnecessary route for potential exploitation.

Perhaps you could have lua_loadtext and lua_loadbinary and ship a lua_load
compatibility function which first tried lua_loadbinary and if that failed
switched to lua_loadtext? This would allow the definition of different
lua_Reader functions for binary and text.

-----Original Message-----
From: [hidden email]
[[hidden email]] On Behalf Of Luiz Henrique de
Figueiredo
Sent: 05 March 2009 10:36
To: Lua list
Subject: Re: future of bytecode verifier

> This approach makes Lua "safe by default" and anyone implementing bytecode
> support is made responsible for the integrity of the bytecodes between
write
> and read operations (for example by restricting to a protected store, or
> even by implementing cryptographic signing).

This would break existing programs, though. And it'd be policy not
mechanisms,
while Lua goes for the oposite.

Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply | Threaded
Open this post in threaded view
|

Re: future of bytecode verifier

Luiz Henrique de Figueiredo
> OK, but I do not think the proposed mechanism is optimal, at the 'C' level.
> Firstly the lua_Reader function replacement has to process the internals of
> the bytecode format thus breaking containment

I'm probably missing something, but testing in a lua_Reader function
whether the input is binary is simply testing whether the first byte is
LUA_SIGNATURE[0], as luaL_loadfile does.

That said, we could write a convenience function like this:
 
typedef struct {
  int first;
  lua_Reader f;
  void *data;
} Safedata;

static const char *safe (lua_State *L, void *ud, size_t *size) {
  Safedata *d = (Safedata*) ud;
  const char *s = d->f(L,d->data,size);
  if (d->first) {
    d->first = 0;
    if (s!=NULL && *size!=0 && s[0]==LUA_SIGNATURE[0])
      luaL_error(L,"cannot load binary files");
  }
  return (*size > 0) ? s : NULL;
}

LUALIB_API int luaL_load (lua_State *L, lua_Reader f, void *data,
                      const char *chunkname, int nobinary) {
  Safedata d;
  d.first=nobinary;
  d.f=f;
  d.data=data;
  return lua_load(L, safe, &d, chunkname);
}


123