Re: [webkit-dev] ExecState::thisObject()

2009-07-14 Thread Geoffrey Garen

That's correct.  Other browser's get this case right.  Here are a
couple test cases you might find interesting:

http://webblaze.org/abarth/tests/protoconfused/test1.html
http://webblaze.org/abarth/tests/protoconfused/test2.html


I tried these tests, with mixed results:

IE8: Exception thrown during load.
Firefox 3.0: mixture of passes and fails on test1.html. Exception  
thrown

during load of test2.html.
Chrome 2.0: Mixture of passes and fails.


Yes.  All the browsers suck on these tests.  :)

Would you like me to go look for more exploitable cases?  It seems
like the only reason not to fix this issue is because we're afraid of
code churn.


I'm just trying to clarify the issue.

Based on your input, I started out thinking that there was a spec  
mandating this behavior, that other browsers followed the spec, and  
that failure to follow the spec was a security hole.


Now I see that there is no spec, there is no clear shared behavior in  
other browsers, and the security holes we know about only pertain to  
cross-origin objects, which would specifically be excluded from this  
change.


So, the motivation for this change is simply that it would establish a  
new, more logical model for cross-frame property access. That's a  
laudable goal. I hope we can make it happen.


Since we're inventing the model, we have some freedom to do what we  
think is simplest and/or most efficient and/or most secure in certain  
edge cases.


Also, once we've established the model, we'll need to propose it to  
some standards body -- probably HTML5.


Also, we're free to fix the easy stuff now and the hard stuff later,  
since leaving some rough edges unfinished will not be a security  
problem.


Geoff
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-14 Thread Adam Barth
On Tue, Jul 14, 2009 at 12:31 PM, Geoffrey Garengga...@apple.com wrote:
 Also, once we've established the model, we'll need to propose it to some
 standards body -- probably HTML5.

I believe the correct spec to describe this behavior is WebIDL, which
controls how the abstract DOM interfaces are realized in ECMAScript.

Adam
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-14 Thread Geoffrey Garen
Also, once we've established the model, we'll need to propose it to  
some

standards body -- probably HTML5.


I believe the correct spec to describe this behavior is WebIDL, which
controls how the abstract DOM interfaces are realized in ECMAScript.


Sounds good.

Geoff
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-14 Thread Eric Seidel
I've made some initial stabs:
https://bugs.webkit.org/show_bug.cgi?id=27276

The bindings need a bunch more cleanup before we can do much more than
that.  I've started filing bugs about the cleanup.

On Tue, Jul 14, 2009 at 12:41 PM, Geoffrey Garengga...@apple.com wrote:
 Also, once we've established the model, we'll need to propose it to some
 standards body -- probably HTML5.

 I believe the correct spec to describe this behavior is WebIDL, which
 controls how the abstract DOM interfaces are realized in ECMAScript.

 Sounds good.

 Geoff

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Geoffrey Garen

1.  Is it correct for the ExecState to carry the thisValue?


As Adam realized later (I think), ExecState carries the value for  
this inside the calling function. It does not carry the object whose  
property is being accessed.


Geoff
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Eric Seidel
Re-sending from correct address.

On Mon, Jul 13, 2009 at 1:23 PM, Eric Seidelesei...@google.com wrote:
 I'm looking at this more today.

 I'm first fixing JSCell::new subclasses to make sure they're always
 allocating in the correct heap.  If we're to map from objects to the
 associated globalobject via the heap, we need to fix allocation first.

 I started by just removing all versions of new (and jsNumberCell,
 etc.) which used ExecState instead of JSGlobalData*


 I'm wondering if I should instead be changing ExecState to carry a
 current global object member (the global object which carries the
 heap that objects should be allocated in, and prototypes should be
 looked up from.  This is different from either the lexical or global
 objects).  That would require fixing many callsites, but probably
 fewer than my current approach.

 -eric

 On Fri, Jul 10, 2009 at 11:08 PM, Adam Barthaba...@webkit.org wrote:
 On Fri, Jul 10, 2009 at 6:29 PM, Maciej Stachowiakm...@apple.com wrote:
 On Jul 10, 2009, at 6:10 PM, Adam Barth wrote:
 That's correct.  Other browser's get this case right.  Here are a
 couple test cases you might find interesting:

 http://webblaze.org/abarth/tests/protoconfused/test1.html
 http://webblaze.org/abarth/tests/protoconfused/test2.html

 The question is how to compute the correct wrapper context in all
 cases.  There are a bunch of approaches that cover 80% of the cases.
 The trick is finding an approach that works for 100% of the causes.

 Well, for DOM Nodes you can almost always chase backpointers all the way up
 to the Document and from there to the Window, but this could be inefficient.
 And there's objects in the DOM that are not Nodes at all, and can't readily
 reach a Node.

 We tried this approach for a while, but we came across CSSValue, which
 has no obvious back pointers.  It's a bit unclear how to do this for
 all Nodes even.  For example, DocType Nodes might not have an
 associated Document.

 It's possible we could change WebCore to have all the appropriate back
 pointers.  However, it might be easier to have all the wrapper objects
 hold the global object directly (or indirectly via their heap
 placement).

 I will ask Sam and Geoff for their thoughts in person if they don't chime in
 on the list.

 Thanks.

 Adam
 ___
 webkit-dev mailing list
 webkit-dev@lists.webkit.org
 http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Geoffrey Garen

Our current thinking is to add a parameter to toJS() to receive the
JSGlobalObject in which to create the wrapper.


Seems logical.

Once we do that, the question is how to find the proper  
JSGlobalObject at each call site.



In most cases, you have another JSObject sitting around that is from
the right JSGlobalObject.  In the document.body example, the getter
for body has the JSDocument from which it gets the body property.  We
can then use Heap::heap(sittingAroundObject)-globalData() to get back
to the right JSGlobalObject.


Heap::heap() will give you a JSGlobalData pointer, but not a  
JSGlobalObject pointer. All JSGlobalObjects in WebCore share the same  
Heap and the same JSGlobalData.


Using a different heap for each JSGlobalObject would be a pretty major  
change.



An alternative is to add state to every JSDOMObject to remember with
which JSGlobalObject it's associated.  This might have memory
overhead.


Almost all DOM access proceeds from [ window ] - [ document ] -  
[ interior stuff ], so it's probably feasible to propagate a window  
pointer along all chains of property access. This would also be a  
pretty major change, though.


In JavaScript, it's trivial to figure out the global object that  
originated execution, and the global object in which the currently  
executing function was defined. So, if script S calls function F, it's  
trivial to figure out the window in which S was loaded, and also the  
window in which F was defined. But figuring out the window from which  
an arbitrary object originated seems challenging.


Geoff
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Geoffrey Garen
Is it definitely right for document.body to make a wrapper using  
prototypes
from the document's host window, rather than from the accessing  
function's

window? What do other browsers do?


That's correct.  Other browser's get this case right.


Is there a particular security or other benefit here, or do we just  
want to make this change to match other browsers?


Geoff

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Geoffrey Garen

I'm first fixing JSCell::new subclasses to make sure they're always
allocating in the correct heap.  If we're to map from objects to the
associated globalobject via the heap, we need to fix allocation  
first.


I'm not sure what you guys have been meaning by the phrase correct  
heap. Barring workers, all WebCore objects are allocated from the  
same heap.



I'm wondering if I should instead be changing ExecState to carry a
current global object member (the global object which carries the
heap that objects should be allocated in, and prototypes should be
looked up from.  This is different from either the lexical or global
objects).  That would require fixing many callsites, but probably
fewer than my current approach.


If you want to pass an argument indicating where something should be  
allocated, I don't think ExecState is the right place to do it.  
ExecState is a read-only pointer into the calling function's stack. It  
can answer questions about the calling function's state, but that's it.


Geoff
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Eric Seidel
On Mon, Jul 13, 2009 at 1:36 PM, Geoffrey Garengga...@apple.com wrote:
 I'm not sure what you guys have been meaning by the phrase correct heap.
 Barring workers, all WebCore objects are allocated from the same heap.

We had wrongly assumed that each window got its own.  OK.  This
invalidates using heaps as a way to get back to a global object, thank
you.

 If you want to pass an argument indicating where something should be
 allocated, I don't think ExecState is the right place to do it. ExecState is
 a read-only pointer into the calling function's stack. It can answer
 questions about the calling function's state, but that's it.

It's important for objects to be allocated with the right prototype
chain, otherwise we will have bugs, some of them security related. :)
Example:

A.html:
iframe name=B href=B.html
scriptB.doSomething();/script

B.html:
iframe name=C href=C.html
scriptfunction doSomething() { return C.contentDocument.body; }/script

C.html:
body

In this example:
A is the dynamicGlobalObject
B is the lexicalGlobalObject
but C is the current global object (the one that the
JSHTMLBodyElement) should be allocated in and from which the
JSHTMLBodyElement prototype chain should come from.  All browsers get
variants of this idiom wrong in different places.


There are two was I can see to fix this:
1.  Pass a current global object through to all toJS calls (lots of
callsites changed)
2.  Store a current global object off of the ExecState (set by the
JS engine before leaving into custom native code for property lookup
or function execution).

I tried #1 this morning, and now think #2 is the cleaner way to go.
I'm very interested in your thoughts.

-eric
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Sam Weinig
On Mon, Jul 13, 2009 at 1:57 PM, Eric Seidel e...@webkit.org wrote:

 On Mon, Jul 13, 2009 at 1:36 PM, Geoffrey Garengga...@apple.com wrote:
  I'm not sure what you guys have been meaning by the phrase correct
 heap.
  Barring workers, all WebCore objects are allocated from the same heap.

 We had wrongly assumed that each window got its own.  OK.  This
 invalidates using heaps as a way to get back to a global object, thank
 you.

  If you want to pass an argument indicating where something should be
  allocated, I don't think ExecState is the right place to do it. ExecState
 is
  a read-only pointer into the calling function's stack. It can answer
  questions about the calling function's state, but that's it.

 It's important for objects to be allocated with the right prototype
 chain, otherwise we will have bugs, some of them security related. :)
 Example:

 A.html:
 iframe name=B href=B.html
 scriptB.doSomething();/script

 B.html:
 iframe name=C href=C.html
 scriptfunction doSomething() { return C.contentDocument.body; }/script

 C.html:
 body

 In this example:
 A is the dynamicGlobalObject
 B is the lexicalGlobalObject
 but C is the current global object (the one that the
 JSHTMLBodyElement) should be allocated in and from which the
 JSHTMLBodyElement prototype chain should come from.  All browsers get
 variants of this idiom wrong in different places.


 There are two was I can see to fix this:
 1.  Pass a current global object through to all toJS calls (lots of
 callsites changed)
 2.  Store a current global object off of the ExecState (set by the
 JS engine before leaving into custom native code for property lookup
 or function execution).

 I tried #1 this morning, and now think #2 is the cleaner way to go.
 I'm very interested in your thoughts.


I discussed this a bit with Darin and Geoff, and we came to the conclusion
that the correct fix is to have each JS DOMObject store a JSGlobalObject
pointer and augment the toJS methods to pass a global object instead of an
ExecState (close to you #1).  I would not advocate storing more data on the
ExecState.

The tricky part will be getting cases the edge cases such as events and
callbacks correct.

-Sam
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Eric Seidel
On Mon, Jul 13, 2009 at 2:18 PM, Sam Weinigsam.wei...@gmail.com wrote:
 I discussed this a bit with Darin and Geoff, and we came to the conclusion
 that the correct fix is to have each JS DOMObject store a JSGlobalObject
 pointer and augment the toJS methods to pass a global object instead of an
 ExecState (close to you #1).

There are classes in JavaScriptCore with mutable prototype chains
which will not be covered by this fix, no?

1.__proto__ for instance, no?

Adam would have to comment as to how much of a concern that would be.

 I would not advocate storing more data on the
 ExecState.
 The tricky part will be getting cases the edge cases such as events and
 callbacks correct.
 -Sam
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Geoffrey Garen

1.  Pass a current global object through to all toJS calls (lots of
callsites changed)
2.  Store a current global object off of the ExecState (set by the
JS engine before leaving into custom native code for property lookup
or function execution).


I discussed this a bit with Darin and Geoff, and we came to the  
conclusion that the correct fix is to have each JS DOMObject store a  
JSGlobalObject pointer and augment the toJS methods to pass a global  
object instead of an ExecState (close to you #1).  I would not  
advocate storing more data on the ExecState.


To add to what Sam just said, I don't think #2 is viable. Where would  
the JS engine get the current global object from?


Geoff
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Maciej Stachowiak


On Jul 13, 2009, at 2:18 PM, Sam Weinig wrote:



I discussed this a bit with Darin and Geoff, and we came to the  
conclusion that the correct fix is to have each JS DOMObject store a  
JSGlobalObject pointer and augment the toJS methods to pass a global  
object instead of an ExecState (close to you #1).


You probably mean in addition to rather than instead of.

 - Maciej

(As a side note, I'm not sure this is really a security issue, since  
we're primarily talking about same-origin access here. For the few  
cases where cross-origin access is allowed, we would *not* want to  
expose the home window's prototype chain. So for Window.postMessage  
for instance, cross-origin access need to give you a distinct wrapper.)


___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Geoffrey Garen
I discussed this a bit with Darin and Geoff, and we came to the  
conclusion that the correct fix is to have each JS DOMObject store  
a JSGlobalObject pointer and augment the toJS methods to pass a  
global object instead of an ExecState (close to you #1).


You probably mean in addition to rather than instead of.


We talked about instead of.

We think the JSGlobalObject will render the ExecState irrelevant,  
since the ExecState was only used to access the heap, which  
JSGlobalObject can do, and to select a prototype, which this fix will  
do.


(As a side note, I'm not sure this is really a security issue, since  
we're primarily talking about same-origin access here. For the few  
cases where cross-origin access is allowed, we would *not* want to  
expose the home window's prototype chain. So for Window.postMessage  
for instance, cross-origin access need to give you a distinct  
wrapper.)


Yeah, probably not a security issue.

Geoff
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Geoffrey Garen
I discussed this a bit with Darin and Geoff, and we came to the  
conclusion
that the correct fix is to have each JS DOMObject store a  
JSGlobalObject
pointer and augment the toJS methods to pass a global object  
instead of an

ExecState (close to you #1).


There are classes in JavaScriptCore with mutable prototype chains
which will not be covered by this fix, no?


After the engine properly constructs an object with the correct  
prototype, the author can change that prototype, yes.


But I don't think that invalidates our strategy for property  
constructing objects with the correct prototype.


Geoff
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Adam Barth
On Mon, Jul 13, 2009 at 1:33 PM, Geoffrey Garengga...@apple.com wrote:
 Is it definitely right for document.body to make a wrapper using
 prototypes
 from the document's host window, rather than from the accessing
 function's
 window? What do other browsers do?

 That's correct.  Other browser's get this case right.

 Is there a particular security or other benefit here, or do we just want to
 make this change to match other browsers?

Our current behavior is buggy, unpredictable, and out of spec.  This
has led to security bugs in the past and will lead to security bugs in
the future.  Is there a particular reason to keep our current
behavior?

Adam
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Adam Barth
On Mon, Jul 13, 2009 at 2:26 PM, Maciej Stachowiakm...@apple.com wrote:
 For the few cases where
 cross-origin access is allowed, we would *not* want to expose the home
 window's prototype chain. So for Window.postMessage for instance,
 cross-origin access need to give you a distinct wrapper.

That's correct.  In fact, Firefox had this exact bug as recently as a year ago.

Adam
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Geoffrey Garen
Is there a particular security or other benefit here, or do we just  
want to

make this change to match other browsers?


Our current behavior is buggy, unpredictable, and out of spec.  This
has led to security bugs in the past and will lead to security bugs in
the future.


I don't disagree with you, but I'm not immediately convinced that a  
large design change will automatically reduce the bug count, either.


Which spec did you have in mind? I'd like to read it.


Is there a particular reason to keep our current behavior?


No, I don't think so -- and I don't mean to object to this idea,  
either. I was just asking for clarification.


Geoff
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Geoffrey Garen
I discussed this a bit with Darin and Geoff, and we came to the  
conclusion that the correct fix is to have each JS DOMObject store  
a JSGlobalObject pointer and augment the toJS methods to pass a  
global object instead of an ExecState (close to you #1).  I would  
not advocate storing more data on the ExecState.


Sam and I just noticed that, to fully support this behavior, any host  
object that lazily constructs function properties using the functions  
in lookup.h must either


(a) change in the same way as DOM objects must change

or

(b) eagerly construct its function properties with the correct  
prototype.



Consider this case, which does not involve a DOM object:

frames[0].Array.prototype.push.__proto__ ==  
Array.prototype.push.__proto__


Geoff
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Adam Barth
On Mon, Jul 13, 2009 at 3:29 PM, Geoffrey Garengga...@apple.com wrote:
 Our current behavior is buggy, unpredictable, and out of spec.  This
 has led to security bugs in the past and will lead to security bugs in
 the future.

 I don't disagree with you, but I'm not immediately convinced that a large
 design change will automatically reduce the bug count, either.

 Which spec did you have in mind? I'd like to read it.

Essentially, the ECMAScript spec requires this.  In spec-land, these
objects are all created at the beginning of time.  The fact that we
create them lazily is what leads to this bug.  Depending on who
touches them first, they end up with different prototype chains, which
doesn't make sense to ECMAScript.

Adam
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Geoffrey Garen

Which spec did you have in mind? I'd like to read it.


Essentially, the ECMAScript spec requires this.  In spec-land, these
objects are all created at the beginning of time.  The fact that we
create them lazily is what leads to this bug.  Depending on who
touches them first, they end up with different prototype chains, which
doesn't make sense to ECMAScript.


I agree that it's strange for an object's behavior to change based on  
which global object accesses it first, but I don't think the ECMA spec  
is a good guide here, since, according to ECMA 262, the very notion of  
more than one global object is invalid.



That's correct.  Other browser's get this case right.  Here are a
couple test cases you might find interesting:

http://webblaze.org/abarth/tests/protoconfused/test1.html
http://webblaze.org/abarth/tests/protoconfused/test2.html


I tried these tests, with mixed results:

IE8: Exception thrown during load.
Firefox 3.0: mixture of passes and fails on test1.html. Exception  
thrown during load of test2.html.

Chrome 2.0: Mixture of passes and fails.

Geoff
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Geoffrey Garen

Yep...  My guess is that (a) is probably better, but you two are more
expert on why we use lazy construction.


Heh -- lazy construction in JSC is even older than I am! :)

The goal is to reduce memory use and startup cost in cases where  
certain functions aren't used. I'm not sure how much of a difference  
it makes in practice.


Geoff
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Maciej Stachowiak


On Jul 13, 2009, at 3:36 PM, Geoffrey Garen wrote:

I discussed this a bit with Darin and Geoff, and we came to the  
conclusion that the correct fix is to have each JS DOMObject store  
a JSGlobalObject pointer and augment the toJS methods to pass a  
global object instead of an ExecState (close to you #1).  I would  
not advocate storing more data on the ExecState.


Sam and I just noticed that, to fully support this behavior, any  
host object that lazily constructs function properties using the  
functions in lookup.h must either


(a) change in the same way as DOM objects must change

or

(b) eagerly construct its function properties with the correct  
prototype.



Consider this case, which does not involve a DOM object:

frames[0].Array.prototype.push.__proto__ ==  
Array.prototype.push.__proto__


Built-in classes work somewhat differently. I believe they use the  
calling function's global object (lexical global object) rather than  
having some notion of home object.


Regards,
Maciej

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Geoffrey Garen

Consider this case, which does not involve a DOM object:

frames[0].Array.prototype.push.__proto__ ==  
Array.prototype.push.__proto__


Built-in classes work somewhat differently. I believe they use the  
calling function's global object (lexical global object) rather  
than having some notion of home object.


In Firefox 3.0, built-ins use a home object.

Geoff
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Adam Barth
On Mon, Jul 13, 2009 at 4:01 PM, Geoffrey Garengga...@apple.com wrote:
 That's correct.  Other browser's get this case right.  Here are a
 couple test cases you might find interesting:

 http://webblaze.org/abarth/tests/protoconfused/test1.html
 http://webblaze.org/abarth/tests/protoconfused/test2.html

 I tried these tests, with mixed results:

 IE8: Exception thrown during load.
 Firefox 3.0: mixture of passes and fails on test1.html. Exception thrown
 during load of test2.html.
 Chrome 2.0: Mixture of passes and fails.

Yes.  All the browsers suck on these tests.  :)

Would you like me to go look for more exploitable cases?  It seems
like the only reason not to fix this issue is because we're afraid of
code churn.

Adam
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Maciej Stachowiak


On Jul 13, 2009, at 3:40 PM, Adam Barth wrote:

On Mon, Jul 13, 2009 at 3:29 PM, Geoffrey Garengga...@apple.com  
wrote:

Our current behavior is buggy, unpredictable, and out of spec.  This
has led to security bugs in the past and will lead to security  
bugs in

the future.


I don't disagree with you, but I'm not immediately convinced that a  
large

design change will automatically reduce the bug count, either.

Which spec did you have in mind? I'd like to read it.


Essentially, the ECMAScript spec requires this.  In spec-land, these
objects are all created at the beginning of time.  The fact that we
create them lazily is what leads to this bug.  Depending on who
touches them first, they end up with different prototype chains, which
doesn't make sense to ECMAScript.


While the behavior you describe seems problematic, I don't think it is  
an ECMAScript violation, since ECMAScript essentially allows host  
objects to do anything. If this is defined by spec, the specs that are  
relevant would be HTML5 and Web IDL. I'm not sure if those clearly  
define the behavior.


 - Maciej

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Adam Barth
On Mon, Jul 13, 2009 at 4:08 PM, Maciej Stachowiakm...@apple.com wrote:
 Built-in classes work somewhat differently. I believe they use the calling
 function's global object (lexical global object) rather than having some
 notion of home object.

You might be thinking of boxing primitive values, which do indeed get
their prototypes from the current lexical scope.

Adam
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Maciej Stachowiak


On Jul 13, 2009, at 4:12 PM, Adam Barth wrote:

On Mon, Jul 13, 2009 at 4:08 PM, Maciej Stachowiakm...@apple.com  
wrote:
Built-in classes work somewhat differently. I believe they use the  
calling
function's global object (lexical global object) rather than  
having some

notion of home object.


You might be thinking of boxing primitive values, which do indeed get
their prototypes from the current lexical scope.


Hmm. Exporting home global object behavior to some of the built-in  
JS types would be more challenging than doing it just for DOM objects.  
Some of the built-in classes are up against the JSC cell size limit.


Regards,
Maciej

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Maciej Stachowiak


On Jul 13, 2009, at 4:11 PM, Adam Barth wrote:

On Mon, Jul 13, 2009 at 4:01 PM, Geoffrey Garengga...@apple.com  
wrote:

That's correct.  Other browser's get this case right.  Here are a
couple test cases you might find interesting:

http://webblaze.org/abarth/tests/protoconfused/test1.html
http://webblaze.org/abarth/tests/protoconfused/test2.html


I tried these tests, with mixed results:

IE8: Exception thrown during load.
Firefox 3.0: mixture of passes and fails on test1.html. Exception  
thrown

during load of test2.html.
Chrome 2.0: Mixture of passes and fails.


Yes.  All the browsers suck on these tests.  :)

Would you like me to go look for more exploitable cases?  It seems
like the only reason not to fix this issue is because we're afraid of
code churn.


My own interest would be in weighing the tradeoffs. In the Pro column:

1) Are there aspects of this issue that create security holes?
2) Are there aspects of this issue that create Web compatibility  
problems?
3) Would enforcing a new consistent behavior for this reduce the  
likelihood of future mistakes that cause material problems?


In the potential Con column:

A) Will there be a performance or memory penalty?
B) Will the change increase code complexity?
C) Is there a risk of introducing regressions with the change?


If the benefits are high, then it's not that important to assess the  
risks - we will just live with them. If the benefits are low but the  
costs are also low, then I'd say having logical behavior wins out.  
It's only if the costs are high and the benefits are low that I'd be  
concerned about making the change at all. I wouldn't say code churn  
is categorically ruled out.


Personally I am convinced that the answers to (3) and (C) are both  
yes, and I don't know about any of the other points.


Regards,
Maciej

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Adam Barth
On Mon, Jul 13, 2009 at 4:20 PM, Maciej Stachowiakm...@apple.com wrote:
 My own interest would be in weighing the tradeoffs. In the Pro column:

 1) Are there aspects of this issue that create security holes?

CVE-2009-1702 is an example of such as security hole.  I'm sure that I
can find more if I look for them.

 2) Are there aspects of this issue that create Web compatibility problems?

I don't know of any web compatibility problems arising from this
behavior.  The great deviation between browsers here makes this less
likely

 3) Would enforcing a new consistent behavior for this reduce the likelihood
 of future mistakes that cause material problems?

You're already convinced the answer here is yes.

 In the potential Con column:

 A) Will there be a performance or memory penalty?

I suspect the new behavior will take more memory, but I don't know how much.

 B) Will the change increase code complexity?

In some cases, the change might actually reduce code complexity.  For
example, if you look at the bindings code around events and database
transactions, we do a lot of machinating to find the right security
context.  Much of this code is buggy.  Having the appropriate
JSGlobalObject nearby might help.

 C) Is there a risk of introducing regressions with the change?

There is indeed a chance of regressions.  We'll want to test thoroughly.

 Personally I am convinced that the answers to (3) and (C) are both yes,
 and I don't know about any of the other points.

I can try to provide more information as best I can.  Another option
is to make this change incrementally and assess the costs as we go.
For example, we could fix the SVG prototypes first.

Adam
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Maciej Stachowiak


On Jul 13, 2009, at 4:34 PM, Adam Barth wrote:


CVE-2009-1702 is an example of such as security hole.  I'm sure that I
can find more if I look for them.


I think objects attached to the global object and accessible cross- 
origin are a special case here. (The advisory cited is about Location  
and History.) Values that can be accessed cross-origin are the most  
likely locus for security issues in this area. And they also likely  
need behavior that's different from the generally proposed pattern,  
since revealing or allowing the mutation of home origin prototypes is  
a security risk.


If security is one motivation for this work, then I'd like us to  
understand the pattern we want to use for cross-origin-accessible  
objects. Should they use the home global object prototype but  
protect it from mutation or access to extended properties, should they  
use the prototype of the referencing frame (lexical global object) or  
something else?





Personally I am convinced that the answers to (3) and (C) are both  
yes,

and I don't know about any of the other points.


I can try to provide more information as best I can.  Another option
is to make this change incrementally and assess the costs as we go.
For example, we could fix the SVG prototypes first.


Doing the change incrementally seems wise, if it is feasible to do so.  
Maybe even a patch demonstrating how it would work for a single class  
could be a good way to evaluate the change. Perhaps separate  
trailblazing examples could be given for both an ordinary class and  
one that is cross-origin accessible.


Regards,
Maciej

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Adam Barth
On Mon, Jul 13, 2009 at 4:59 PM, Maciej Stachowiakm...@apple.com wrote:
 If security is one motivation for this work, then I'd like us to understand
 the pattern we want to use for cross-origin-accessible objects. Should they
 use the home global object prototype but protect it from mutation or
 access to extended properties, should they use the prototype of the
 referencing frame (lexical global object) or something else?

I can study this question, but I believe Firefox solves this problem
by having cross-origin viewers of these properties see a fresh copy
of the object that isn't === the object as seen by same-origin
viewers.  The fresh copy ignores any changes the page might has made
to the object and has a prototype chain connects to the viewer's
prototypes.  If two different cross-origin viewers look at the same
object, they each see fresh copies.

 Doing the change incrementally seems wise, if it is feasible to do so. Maybe
 even a patch demonstrating how it would work for a single class could be a
 good way to evaluate the change. Perhaps separate trailblazing examples
 could be given for both an ordinary class and one that is cross-origin
 accessible.

Sounds like a plan.

Thanks for all your input on this topic.

Adam
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-13 Thread Maciej Stachowiak


On Jul 13, 2009, at 5:34 PM, Adam Barth wrote:

On Mon, Jul 13, 2009 at 4:59 PM, Maciej Stachowiakm...@apple.com  
wrote:
If security is one motivation for this work, then I'd like us to  
understand
the pattern we want to use for cross-origin-accessible objects.  
Should they
use the home global object prototype but protect it from mutation  
or

access to extended properties, should they use the prototype of the
referencing frame (lexical global object) or something else?


I can study this question, but I believe Firefox solves this problem
by having cross-origin viewers of these properties see a fresh copy
of the object that isn't === the object as seen by same-origin
viewers.  The fresh copy ignores any changes the page might has made
to the object and has a prototype chain connects to the viewer's
prototypes.  If two different cross-origin viewers look at the same
object, they each see fresh copies.


That pattern sounds workable.

Regards,
Maciej

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-11 Thread Adam Barth
On Fri, Jul 10, 2009 at 6:29 PM, Maciej Stachowiakm...@apple.com wrote:
 On Jul 10, 2009, at 6:10 PM, Adam Barth wrote:
 That's correct.  Other browser's get this case right.  Here are a
 couple test cases you might find interesting:

 http://webblaze.org/abarth/tests/protoconfused/test1.html
 http://webblaze.org/abarth/tests/protoconfused/test2.html

 The question is how to compute the correct wrapper context in all
 cases.  There are a bunch of approaches that cover 80% of the cases.
 The trick is finding an approach that works for 100% of the causes.

 Well, for DOM Nodes you can almost always chase backpointers all the way up
 to the Document and from there to the Window, but this could be inefficient.
 And there's objects in the DOM that are not Nodes at all, and can't readily
 reach a Node.

We tried this approach for a while, but we came across CSSValue, which
has no obvious back pointers.  It's a bit unclear how to do this for
all Nodes even.  For example, DocType Nodes might not have an
associated Document.

It's possible we could change WebCore to have all the appropriate back
pointers.  However, it might be easier to have all the wrapper objects
hold the global object directly (or indirectly via their heap
placement).

 I will ask Sam and Geoff for their thoughts in person if they don't chime in
 on the list.

Thanks.

Adam
___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-10 Thread Adam Barth
Re-sent with correct address.

On Fri, Jul 10, 2009 at 5:55 PM, Adam Barthaba...@eecs.berkeley.edu wrote:
 Eric and I spent some more time this afternoon looking at this.  We
 don't think the ExecState::thisValue() approach is going to work.  We
 implemented hacky version to experiment with, but the problem is with
 cases like this:

 document.body

 In evaluating this case, the this value isn't what we want because
 our computed thisValue is for the running function, not for the
 getter.

 Our current thinking is to add a parameter to toJS() to receive the
 JSGlobalObject in which to create the wrapper.  Once we do that, the
 question is how to find the proper JSGlobalObject at each call site.

 In most cases, you have another JSObject sitting around that is from
 the right JSGlobalObject.  In the document.body example, the getter
 for body has the JSDocument from which it gets the body property.  We
 can then use Heap::heap(sittingAroundObject)-globalData() to get back
 to the right JSGlobalObject.

 Of course, this requires that objects get allocated in the right heap,
 which isn't quite the case at the moment because the new operator
 takes an ExecState and chooses the heap based on the
 lexicalGlobalObject.

 An alternative is to add state to every JSDOMObject to remember with
 which JSGlobalObject it's associated.  This might have memory
 overhead.

 Thoughts?

 Adam


 On Fri, Jul 10, 2009 at 3:59 PM, Eric Seidele...@webkit.org wrote:
 Geoff, Gavin, Sam, Maciej (and any other JSC experts):

 Adam and I are fixing:
 https://bugs.webkit.org/show_bug.cgi?id=27088

 Fix: toJS needs to use the correct global object.  The correct global
 object should come from whatever this is calling into the native
 code which is using toJS.
 (e.g. document.body.  It doesn't matter how/when you access it, the
 correct prototype comes from whichever global object which the
 document was created from.)


 BACKGROUND EXAMPLE:

 scriptframes[0].document.createElement(foo)/script

 Should use thisValue as passed into:
 JSValue JSC_HOST_CALL
 jsDocumentPrototypeFunctionCreateElement(ExecState* exec, JSObject*,
 JSValue thisValue, const ArgList args)

 We believe the easiest way to get the correct globalData is via:
 *Heap::heap(thisValue)-globalData()



 QUESTIONS:

 We do not need to change the signature of all toJS implementations if
 the ExecState can carry the thisValue for us.

 ExecState::thisValue() already exists, but ExecState::codeBlock()
 seems NULL in our case.  (thisValue() seems used by the debugger).


 1.  Is it correct for the ExecState to carry the thisValue?

 2.  If ExecState is OK to carry thisValue how should we fix it to be
 non-NULL in jsDocumentPrototypeFunctionCreateElement (and other
 places)?


 Thanks,
 Eric  Adam
 ___
 webkit-dev mailing list
 webkit-dev@lists.webkit.org
 http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-10 Thread Maciej Stachowiak


On Jul 10, 2009, at 5:55 PM, Adam Barth wrote:


Eric and I spent some more time this afternoon looking at this.  We
don't think the ExecState::thisValue() approach is going to work.  We
implemented hacky version to experiment with, but the problem is with
cases like this:

document.body

In evaluating this case, the this value isn't what we want because
our computed thisValue is for the running function, not for the
getter.


Is it definitely right for document.body to make a wrapper using  
prototypes from the document's host window, rather than from the  
accessing function's window? What do other browsers do?


 - Maciej

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-10 Thread Adam Barth
Sent again from the right address.  Gmail hates me today.

On Fri, Jul 10, 2009 at 6:10 PM, Adam Barthaba...@eecs.berkeley.edu wrote:
 On Fri, Jul 10, 2009 at 6:04 PM, Maciej Stachowiakm...@apple.com wrote:
 On Jul 10, 2009, at 5:55 PM, Adam Barth wrote:
 Eric and I spent some more time this afternoon looking at this.  We
 don't think the ExecState::thisValue() approach is going to work.  We
 implemented hacky version to experiment with, but the problem is with
 cases like this:

 document.body

 In evaluating this case, the this value isn't what we want because
 our computed thisValue is for the running function, not for the
 getter.

 Is it definitely right for document.body to make a wrapper using prototypes
 from the document's host window, rather than from the accessing function's
 window? What do other browsers do?

 That's correct.  Other browser's get this case right.  Here are a
 couple test cases you might find interesting:

 http://webblaze.org/abarth/tests/protoconfused/test1.html
 http://webblaze.org/abarth/tests/protoconfused/test2.html

 The question is how to compute the correct wrapper context in all
 cases.  There are a bunch of approaches that cover 80% of the cases.
 The trick is finding an approach that works for 100% of the causes.

 Adam

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev


Re: [webkit-dev] ExecState::thisObject()

2009-07-10 Thread Maciej Stachowiak


(Trimming Cc's since the relevant people are on webkit-dev anyway.)

On Jul 10, 2009, at 6:10 PM, Adam Barth wrote:

On Fri, Jul 10, 2009 at 6:04 PM, Maciej Stachowiakm...@apple.com  
wrote:


Is it definitely right for document.body to make a wrapper using  
prototypes
from the document's host window, rather than from the accessing  
function's

window? What do other browsers do?


That's correct.  Other browser's get this case right.  Here are a
couple test cases you might find interesting:

http://webblaze.org/abarth/tests/protoconfused/test1.html
http://webblaze.org/abarth/tests/protoconfused/test2.html

The question is how to compute the correct wrapper context in all
cases.  There are a bunch of approaches that cover 80% of the cases.
The trick is finding an approach that works for 100% of the causes.


Well, for DOM Nodes you can almost always chase backpointers all the  
way up to the Document and from there to the Window, but this could be  
inefficient. And there's objects in the DOM that are not Nodes at all,  
and can't readily reach a Node. I will ask Sam and Geoff for their  
thoughts in person if they don't chime in on the list.


 - Maciej

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-dev