Re: [Pharo-project] test crashing the cog vm

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-project] test crashing the cog vm

Eliot Miranda-2
 


On Thu, Mar 24, 2011 at 11:42 AM, Igor Stasenko <[hidden email]> wrote:
On 24 March 2011 19:34, Eliot Miranda <[hidden email]> wrote:
>
>
> On Tue, Mar 22, 2011 at 5:34 AM, Stéphane Ducasse
> <[hidden email]> wrote:
>>
>> But why we could not have a byecode validator at the image level that
>> first make sure that byte code are in sync with the format of the objects.
>
> Because it can be compromised.  An in-image verifier is subject to attack,
> and could be disabled by an attack that got past the in-image verifier
> before it got a chance to run.  An in-VM verifier is not possible to
> side-step because it is the only way to execute code.  So an in-VM verifier
> can be secure but an in-image one can't and so is pointless.
>
For real hacker there's nothing impossible :)

True, but it can be much harder.  How would you attempt to hack past the fact that the interpreter and JIT code, including the verifier, is in read-only memory?  If this is the only route to create executable code, and it always verifies the bytecode before it executes then it is secure right?

[there are issues; one doesn't want to verify a method each time it is activated in the interpreter, but e.g. a bit in the header saying "this method has been verified" might be easy to compromise.  I'm not sure it is though, because one big advantage of the current funky method format (half literals, half btes) is that there's only one primitive to construct a method and it has to have a valid header, and there's only one way to modify the header, objectAt:put:.  So as far as I can see the VM can in fact preserve the integrty a header flag bit that says "this method has been verified".  Am I right or wrong?]
 

Right now its not possible to split image to layered onion (like
operating system does, where you have kernel level,
and user level), but i think (at least in theory) such composition
could be implemented, except that sure thing
we don't have resources to invest in this direction.

It is actually nice field for research (hello guys from academy :)

--
Best regards,
Igor Stasenko AKA sig.


Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-project] test crashing the cog vm

Igor Stasenko

On 24 March 2011 19:53, Eliot Miranda <[hidden email]> wrote:

>
>
>
> On Thu, Mar 24, 2011 at 11:42 AM, Igor Stasenko <[hidden email]> wrote:
>>
>> On 24 March 2011 19:34, Eliot Miranda <[hidden email]> wrote:
>> >
>> >
>> > On Tue, Mar 22, 2011 at 5:34 AM, Stéphane Ducasse
>> > <[hidden email]> wrote:
>> >>
>> >> But why we could not have a byecode validator at the image level that
>> >> first make sure that byte code are in sync with the format of the objects.
>> >
>> > Because it can be compromised.  An in-image verifier is subject to attack,
>> > and could be disabled by an attack that got past the in-image verifier
>> > before it got a chance to run.  An in-VM verifier is not possible to
>> > side-step because it is the only way to execute code.  So an in-VM verifier
>> > can be secure but an in-image one can't and so is pointless.
>> >
>> For real hacker there's nothing impossible :)
>
> True, but it can be much harder.  How would you attempt to hack past the fact that the interpreter and JIT code, including the verifier, is in read-only memory?  If this is the only route to create executable code, and it always verifies the bytecode before it executes then it is secure right?
> [there are issues; one doesn't want to verify a method each time it is activated in the interpreter, but e.g. a bit in the header saying "this method has been verified" might be easy to compromise.  I'm not sure it is though, because one big advantage of the current funky method format (half literals, half btes) is that there's only one primitive to construct a method and it has to have a valid header, and there's only one way to modify the header, objectAt:put:.  So as far as I can see the VM can in fact preserve the integrty a header flag bit that says "this method has been verified".  Am I right or wrong?]

To my thinking, verification needs to be performed at the moment of
installation method to some class.
Because if method is not installed anywhere, performing verification
is just a waste of time,
and moreover it could be erroneous and tedious, because compiler could
fill method's state in multiple stages.

Instead, if we could have a primitive
installMethod: aMethod forClass: aClass
then we can put verification there as well as sealing compiled method
for the rest of its life.
As well, as we no longer need to flush cache (like
MethodDictionary>>at:put: does), because VM can do this
correctly in given primitive so, it is an additional benefit.

For this to work, we should also prevent modification to methods
dictionary once it assigned to particular class
(we will need additional primitives for removing/replacing methods in
given dictionary).


--
Best regards,
Igor Stasenko AKA sig.
Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-project] test crashing the cog vm

Levente Uzonyi-2
 
On Thu, 24 Mar 2011, Igor Stasenko wrote:

>
> On 24 March 2011 19:53, Eliot Miranda <[hidden email]> wrote:
>>
>>
>>
>> On Thu, Mar 24, 2011 at 11:42 AM, Igor Stasenko <[hidden email]> wrote:
>>>
>>> On 24 March 2011 19:34, Eliot Miranda <[hidden email]> wrote:
>>>>
>>>>
>>>> On Tue, Mar 22, 2011 at 5:34 AM, Stéphane Ducasse
>>>> <[hidden email]> wrote:
>>>>>
>>>>> But why we could not have a byecode validator at the image level that
>>>>> first make sure that byte code are in sync with the format of the objects.
>>>>
>>>> Because it can be compromised.  An in-image verifier is subject to attack,
>>>> and could be disabled by an attack that got past the in-image verifier
>>>> before it got a chance to run.  An in-VM verifier is not possible to
>>>> side-step because it is the only way to execute code.  So an in-VM verifier
>>>> can be secure but an in-image one can't and so is pointless.
>>>>
>>> For real hacker there's nothing impossible :)
>>
>> True, but it can be much harder.  How would you attempt to hack past the fact that the interpreter and JIT code, including the verifier, is in read-only memory?  If this is the only route to create executable code, and it always verifies the bytecode before it executes then it is secure right?
>> [there are issues; one doesn't want to verify a method each time it is activated in the interpreter, but e.g. a bit in the header saying "this method has been verified" might be easy to compromise.  I'm not sure it is though, because one big advantage of the current funky method format (half literals, half btes) is that there's only one primitive to construct a method and it has to have a valid header, and there's only one way to modify the header, objectAt:put:.  So as far as I can see the VM can in fact preserve the integrty a header flag bit that says "this method has been verified".  Am I right or wrong?]
>
> To my thinking, verification needs to be performed at the moment of
> installation method to some class.
> Because if method is not installed anywhere, performing verification
> is just a waste of time,
> and moreover it could be erroneous and tedious, because compiler could
> fill method's state in multiple stages.
>
> Instead, if we could have a primitive
> installMethod: aMethod forClass: aClass
> then we can put verification there as well as sealing compiled method
> for the rest of its life.
> As well, as we no longer need to flush cache (like
> MethodDictionary>>at:put: does), because VM can do this
> correctly in given primitive so, it is an additional benefit.
>
> For this to work, we should also prevent modification to methods
> dictionary once it assigned to particular class
> (we will need additional primitives for removing/replacing methods in
> given dictionary).
Note that are primitives (188 and 189) to execute methods which are not
installed in the object's class's method dictionary.

Also note that this effort is against the "keep the VM simple, move as
much stuff to the image side as possible" paradigm.


Levente

>
>
> --
> Best regards,
> Igor Stasenko AKA sig.
>
Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-project] test crashing the cog vm

Igor Stasenko

2011/3/24 Levente Uzonyi <[hidden email]>:

>
> On Thu, 24 Mar 2011, Igor Stasenko wrote:
>
>>
>> On 24 March 2011 19:53, Eliot Miranda <[hidden email]> wrote:
>>>
>>>
>>>
>>> On Thu, Mar 24, 2011 at 11:42 AM, Igor Stasenko <[hidden email]> wrote:
>>>>
>>>> On 24 March 2011 19:34, Eliot Miranda <[hidden email]> wrote:
>>>>>
>>>>>
>>>>> On Tue, Mar 22, 2011 at 5:34 AM, Stéphane Ducasse
>>>>> <[hidden email]> wrote:
>>>>>>
>>>>>> But why we could not have a byecode validator at the image level that
>>>>>> first make sure that byte code are in sync with the format of the objects.
>>>>>
>>>>> Because it can be compromised.  An in-image verifier is subject to attack,
>>>>> and could be disabled by an attack that got past the in-image verifier
>>>>> before it got a chance to run.  An in-VM verifier is not possible to
>>>>> side-step because it is the only way to execute code.  So an in-VM verifier
>>>>> can be secure but an in-image one can't and so is pointless.
>>>>>
>>>> For real hacker there's nothing impossible :)
>>>
>>> True, but it can be much harder.  How would you attempt to hack past the fact that the interpreter and JIT code, including the verifier, is in read-only memory?  If this is the only route to create executable code, and it always verifies the bytecode before it executes then it is secure right?
>>> [there are issues; one doesn't want to verify a method each time it is activated in the interpreter, but e.g. a bit in the header saying "this method has been verified" might be easy to compromise.  I'm not sure it is though, because one big advantage of the current funky method format (half literals, half btes) is that there's only one primitive to construct a method and it has to have a valid header, and there's only one way to modify the header, objectAt:put:.  So as far as I can see the VM can in fact preserve the integrty a header flag bit that says "this method has been verified".  Am I right or wrong?]
>>
>> To my thinking, verification needs to be performed at the moment of
>> installation method to some class.
>> Because if method is not installed anywhere, performing verification
>> is just a waste of time,
>> and moreover it could be erroneous and tedious, because compiler could
>> fill method's state in multiple stages.
>>
>> Instead, if we could have a primitive
>> installMethod: aMethod forClass: aClass
>> then we can put verification there as well as sealing compiled method
>> for the rest of its life.
>> As well, as we no longer need to flush cache (like
>> MethodDictionary>>at:put: does), because VM can do this
>> correctly in given primitive so, it is an additional benefit.
>>
>> For this to work, we should also prevent modification to methods
>> dictionary once it assigned to particular class
>> (we will need additional primitives for removing/replacing methods in
>> given dictionary).
>
> Note that are primitives (188 and 189) to execute methods which are not installed in the object's class's method dictionary.
>
Yep.. so these should be considered as well.

> Also note that this effort is against the "keep the VM simple, move as much stuff to the image side as possible" paradigm.
>

Yes, you are right.
It is much easier to patch VM instead of making truly secure design at
language side.
(That's what i like in Newspeak design, except parts which i don't like ;) )

And yes, putting extra constraints in VM will ensure that in future we
will have much less space for maneuver.

>
> Levente
>


--
Best regards,
Igor Stasenko AKA sig.
Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-project] test crashing the cog vm

Eliot Miranda-2
In reply to this post by Igor Stasenko
 


On Thu, Mar 24, 2011 at 12:19 PM, Igor Stasenko <[hidden email]> wrote:

On 24 March 2011 19:53, Eliot Miranda <[hidden email]> wrote:
>
>
>
> On Thu, Mar 24, 2011 at 11:42 AM, Igor Stasenko <[hidden email]> wrote:
>>
>> On 24 March 2011 19:34, Eliot Miranda <[hidden email]> wrote:
>> >
>> >
>> > On Tue, Mar 22, 2011 at 5:34 AM, Stéphane Ducasse
>> > <[hidden email]> wrote:
>> >>
>> >> But why we could not have a byecode validator at the image level that
>> >> first make sure that byte code are in sync with the format of the objects.
>> >
>> > Because it can be compromised.  An in-image verifier is subject to attack,
>> > and could be disabled by an attack that got past the in-image verifier
>> > before it got a chance to run.  An in-VM verifier is not possible to
>> > side-step because it is the only way to execute code.  So an in-VM verifier
>> > can be secure but an in-image one can't and so is pointless.
>> >
>> For real hacker there's nothing impossible :)
>
> True, but it can be much harder.  How would you attempt to hack past the fact that the interpreter and JIT code, including the verifier, is in read-only memory?  If this is the only route to create executable code, and it always verifies the bytecode before it executes then it is secure right?
> [there are issues; one doesn't want to verify a method each time it is activated in the interpreter, but e.g. a bit in the header saying "this method has been verified" might be easy to compromise.  I'm not sure it is though, because one big advantage of the current funky method format (half literals, half btes) is that there's only one primitive to construct a method and it has to have a valid header, and there's only one way to modify the header, objectAt:put:.  So as far as I can see the VM can in fact preserve the integrty a header flag bit that says "this method has been verified".  Am I right or wrong?]

To my thinking, verification needs to be performed at the moment of
installation method to some class.
Because if method is not installed anywhere, performing verification
is just a waste of time,
and moreover it could be erroneous and tedious, because compiler could
fill method's state in multiple stages.

Doesn't work. For example, doits are no longer installed in any class.  The time for verification is either when a method is first run by the VM (e.g. by checking a bit on every activation), or when a method is entered into a lookup cache, or when it is JITted.  One may have to check on first run because of things like doits where the method is not entered into the method lookup cache before being executed.  But since interpreter activation requires header access (to extract the number of temporaries) there is very little overhead in checking an additional header bit on every activation.  Hence KISS says to check the "is verified" bit on every interpreter activation or JIT of a method, running the verification test if the flag is unset.  One also has to make methods immutable for this approach to work.
 

Instead, if we could have a primitive
installMethod: aMethod forClass: aClass
then we can put verification there as well as sealing compiled method
for the rest of its life.
As well, as we no longer need to flush cache (like
MethodDictionary>>at:put: does), because VM can do this
correctly in given primitive so, it is an additional benefit.

I don't like pushing method dictionaries down into the VM at all.
 

For this to work, we should also prevent modification to methods
dictionary once it assigned to particular class
(we will need additional primitives for removing/replacing methods in
given dictionary).


--
Best regards,
Igor Stasenko AKA sig.

Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-project] test crashing the cog vm

Eliot Miranda-2
In reply to this post by Levente Uzonyi-2
 


2011/3/24 Levente Uzonyi <[hidden email]>
 
On Thu, 24 Mar 2011, Igor Stasenko wrote:


On 24 March 2011 19:53, Eliot Miranda <[hidden email]> wrote:



On Thu, Mar 24, 2011 at 11:42 AM, Igor Stasenko <[hidden email]> wrote:

On 24 March 2011 19:34, Eliot Miranda <[hidden email]> wrote:


On Tue, Mar 22, 2011 at 5:34 AM, Stéphane Ducasse
<[hidden email]> wrote:

But why we could not have a byecode validator at the image level that
first make sure that byte code are in sync with the format of the objects.

Because it can be compromised.  An in-image verifier is subject to attack,
and could be disabled by an attack that got past the in-image verifier
before it got a chance to run.  An in-VM verifier is not possible to
side-step because it is the only way to execute code.  So an in-VM verifier
can be secure but an in-image one can't and so is pointless.

For real hacker there's nothing impossible :)

True, but it can be much harder.  How would you attempt to hack past the fact that the interpreter and JIT code, including the verifier, is in read-only memory?  If this is the only route to create executable code, and it always verifies the bytecode before it executes then it is secure right?
[there are issues; one doesn't want to verify a method each time it is activated in the interpreter, but e.g. a bit in the header saying "this method has been verified" might be easy to compromise.  I'm not sure it is though, because one big advantage of the current funky method format (half literals, half btes) is that there's only one primitive to construct a method and it has to have a valid header, and there's only one way to modify the header, objectAt:put:.  So as far as I can see the VM can in fact preserve the integrty a header flag bit that says "this method has been verified".  Am I right or wrong?]

To my thinking, verification needs to be performed at the moment of
installation method to some class.
Because if method is not installed anywhere, performing verification
is just a waste of time,
and moreover it could be erroneous and tedious, because compiler could
fill method's state in multiple stages.

Instead, if we could have a primitive
installMethod: aMethod forClass: aClass
then we can put verification there as well as sealing compiled method
for the rest of its life.
As well, as we no longer need to flush cache (like
MethodDictionary>>at:put: does), because VM can do this
correctly in given primitive so, it is an additional benefit.

For this to work, we should also prevent modification to methods
dictionary once it assigned to particular class
(we will need additional primitives for removing/replacing methods in
given dictionary).

Note that are primitives (188 and 189) to execute methods which are not installed in the object's class's method dictionary.

+1
 

Also note that this effort is against the "keep the VM simple, move as much stuff to the image side as possible" paradigm.

+1
 


Levente



--
Best regards,
Igor Stasenko AKA sig.