[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.2.1-2-29-g5dbcb1c

Michael Gilbert michael.s.gilbert at gmail.com
Tue Jun 29 04:11:33 UTC 2010


The following commit has been merged in the debian/unstable branch:
commit 9271a6d9c4faa6977a054bf15690753b90d8733b
Author: Michael Gilbert <michael.s.gilbert at gmail.com>
Date:   Mon Jun 28 21:50:04 2010 -0400

    fix cve-2010-1758

diff --git a/WebCore/dom/ContainerNode.cpp b/WebCore/dom/ContainerNode.cpp
index fb2852f..c17489a 100644
--- a/WebCore/dom/ContainerNode.cpp
+++ b/WebCore/dom/ContainerNode.cpp
@@ -292,19 +292,32 @@ void ContainerNode::willRemove()
     Node::willRemove();
 }
 
-static ExceptionCode willRemoveChild(Node *child)
+static void willRemoveChild(Node* child)
 {
-    ExceptionCode ec = 0;
+    // update auxiliary doc info (e.g. iterators) to note that node is being removed
+    child->document()->nodeWillBeRemoved(child);
+    child->document()->incDOMTreeVersion();
 
     // fire removed from document mutation events.
     dispatchChildRemovalEvents(child);
-    if (ec)
-        return ec;
 
     if (child->attached())
         child->willRemove();
-    
-    return 0;
+}
+
+static void willRemoveChildren(ContainerNode* container)
+{
+    container->document()->nodeChildrenWillBeRemoved(container);
+    container->document()->incDOMTreeVersion();
+
+    // FIXME: Adding new children from event handlers can cause an infinite loop here.
+    for (RefPtr<Node> child = container->firstChild(); child; child = child->nextSibling()) {
+        // fire removed from document mutation events.
+        dispatchChildRemovalEvents(child.get());
+
+        if (child->attached())
+            child->willRemove();
+    }
 }
 
 bool ContainerNode::removeChild(Node* oldChild, ExceptionCode& ec)
@@ -328,10 +341,7 @@ bool ContainerNode::removeChild(Node* oldChild, ExceptionCode& ec)
     }
 
     RefPtr<Node> child = oldChild;
-
-    ec = willRemoveChild(child.get());
-    if (ec)
-        return false;
+    willRemoveChild(child.get());
 
     // Mutation events might have moved this child into a different parent.
     if (child->parentNode() != this) {
@@ -399,14 +409,12 @@ bool ContainerNode::removeChildren()
         return false;
 
     // The container node can be removed from event handlers.
-    RefPtr<Node> protect(this);
-    
+    RefPtr<ContainerNode> protect(this);
+
     // Do any prep work needed before actually starting to detach
     // and remove... e.g. stop loading frames, fire unload events.
-    // FIXME: Adding new children from event handlers can cause an infinite loop here.
-    for (RefPtr<Node> n = m_firstChild; n; n = n->nextSibling())
-        willRemoveChild(n.get());
-    
+    willRemoveChildren(protect.get());
+
     // exclude this node when looking for removed focusedNode since only children will be removed
     document()->removeFocusedNodeOfSubtree(this, true);
 
@@ -936,6 +944,8 @@ static void dispatchChildInsertionEvents(Node* child)
 
 static void dispatchChildRemovalEvents(Node* child)
 {
+    ASSERT(!eventDispatchForbidden());
+
 #if ENABLE(INSPECTOR)    
     if (Page* page = child->document()->page()) {
         if (InspectorController* inspectorController = page->inspectorController())
@@ -946,11 +956,6 @@ static void dispatchChildRemovalEvents(Node* child)
     RefPtr<Node> c = child;
     RefPtr<Document> document = child->document();
 
-    // update auxiliary doc info (e.g. iterators) to note that node is being removed
-    document->nodeWillBeRemoved(child);
-
-    document->incDOMTreeVersion();
-
     // dispatch pre-removal mutation events
     if (c->parentNode() && document->hasListenerType(Document::DOMNODEREMOVED_LISTENER))
         c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeRemovedEvent, true, c->parentNode()));
diff --git a/WebCore/dom/Document.cpp b/WebCore/dom/Document.cpp
index c888afa..3d305b6 100644
--- a/WebCore/dom/Document.cpp
+++ b/WebCore/dom/Document.cpp
@@ -2879,6 +2879,28 @@ void Document::nodeChildrenChanged(ContainerNode* container)
     }
 }
 
+void Document::nodeChildrenWillBeRemoved(ContainerNode* container)
+{
+    if (!disableRangeMutation(page())) {
+        HashSet<Range*>::const_iterator end = m_ranges.end();
+        for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
+            (*it)->nodeChildrenWillBeRemoved(container);
+    }
+
+    HashSet<NodeIterator*>::const_iterator nodeIteratorsEnd = m_nodeIterators.end();
+    for (HashSet<NodeIterator*>::const_iterator it = m_nodeIterators.begin(); it != nodeIteratorsEnd; ++it) {
+        for (Node* n = container->firstChild(); n; n = n->nextSibling())
+            (*it)->nodeWillBeRemoved(n);
+    }
+
+    if (Frame* frame = this->frame()) {
+        for (Node* n = container->firstChild(); n; n = n->nextSibling()) {
+            frame->selection()->nodeWillBeRemoved(n);
+            frame->dragCaretController()->nodeWillBeRemoved(n);
+        }
+    }
+}
+
 void Document::nodeWillBeRemoved(Node* n)
 {
     HashSet<NodeIterator*>::const_iterator nodeIteratorsEnd = m_nodeIterators.end();
diff --git a/WebCore/dom/Document.h b/WebCore/dom/Document.h
index df87ebd..1f4e22c 100644
--- a/WebCore/dom/Document.h
+++ b/WebCore/dom/Document.h
@@ -611,6 +611,9 @@ public:
     void detachRange(Range*);
 
     void nodeChildrenChanged(ContainerNode*);
+    // nodeChildrenWillBeRemoved is used when removing all node children at once.
+    void nodeChildrenWillBeRemoved(ContainerNode*);
+    // nodeWillBeRemoved is only safe when removing one node at a time.
     void nodeWillBeRemoved(Node*);
 
     void textInserted(Node*, unsigned offset, unsigned length);
diff --git a/WebCore/dom/Range.cpp b/WebCore/dom/Range.cpp
index 52d1785..689b590 100644
--- a/WebCore/dom/Range.cpp
+++ b/WebCore/dom/Range.cpp
@@ -1716,6 +1716,31 @@ void Range::nodeChildrenChanged(ContainerNode* container)
     boundaryNodeChildrenChanged(m_end, container);
 }
 
+static inline void boundaryNodeChildrenWillBeRemoved(RangeBoundaryPoint& boundary, ContainerNode* container)
+{
+    for (Node* nodeToBeRemoved = container->firstChild(); nodeToBeRemoved; nodeToBeRemoved = nodeToBeRemoved->nextSibling()) {
+        if (boundary.childBefore() == nodeToBeRemoved) {
+            boundary.setToStartOfNode(container);
+            return;
+        }
+
+        for (Node* n = boundary.container(); n; n = n->parentNode()) {
+            if (n == nodeToBeRemoved) {
+                boundary.setToStartOfNode(container);
+                return;
+            }
+        }
+    }
+}
+
+void Range::nodeChildrenWillBeRemoved(ContainerNode* container)
+{
+    ASSERT(container);
+    ASSERT(container->document() == m_ownerDocument);
+    boundaryNodeChildrenWillBeRemoved(m_start, container);
+    boundaryNodeChildrenWillBeRemoved(m_end, container);
+}
+
 static inline void boundaryNodeWillBeRemoved(RangeBoundaryPoint& boundary, Node* nodeToBeRemoved)
 {
     if (boundary.childBefore() == nodeToBeRemoved) {
diff --git a/WebCore/dom/Range.h b/WebCore/dom/Range.h
index fd0f66a..bfddd32 100644
--- a/WebCore/dom/Range.h
+++ b/WebCore/dom/Range.h
@@ -111,6 +111,7 @@ public:
     void textQuads(Vector<FloatQuad>&, bool useSelectionHeight = false);
 
     void nodeChildrenChanged(ContainerNode*);
+    void nodeChildrenWillBeRemoved(ContainerNode*);
     void nodeWillBeRemoved(Node*);
 
     void textInserted(Node*, unsigned offset, unsigned length);
diff --git a/debian/changelog b/debian/changelog
index fdb0fcd..d78a2e1 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -16,6 +16,7 @@ webkit (1.2.1-3) UNRELEASED; urgency=low
     may be duplicated as cve-2010-1767 in mitre's cve database).
   * Fix cve-2010-1664: possible code execution due to improper html5 media
     handling.
+  * Fix cve-2010-1758: possible code execution in xml dom processor.
 
  -- Michael Gilbert <michael.s.gilbert at gmail.com>  Thu, 27 May 2010 20:36:41 -0400
 
diff --git a/debian/patches/cve-2010-1758.patch b/debian/patches/cve-2010-1758.patch
new file mode 100644
index 0000000..79f7cde
--- /dev/null
+++ b/debian/patches/cve-2010-1758.patch
@@ -0,0 +1,193 @@
+escription: fix cve-2010-1758
+author: Michael Gilbert <michael.s.gilbert at gmail.com>
+origin: http://trac.webkit.org/changeset/59098
+Index: webkit-1.2.1/WebCore/dom/Document.h
+===================================================================
+--- webkit-1.2.1.orig/WebCore/dom/Document.h	2010-05-13 16:31:30.000000000 -0400
++++ webkit-1.2.1/WebCore/dom/Document.h	2010-06-28 21:48:38.000000000 -0400
+@@ -611,6 +611,9 @@
+     void detachRange(Range*);
+ 
+     void nodeChildrenChanged(ContainerNode*);
++    // nodeChildrenWillBeRemoved is used when removing all node children at once.
++    void nodeChildrenWillBeRemoved(ContainerNode*);
++    // nodeWillBeRemoved is only safe when removing one node at a time.
+     void nodeWillBeRemoved(Node*);
+ 
+     void textInserted(Node*, unsigned offset, unsigned length);
+Index: webkit-1.2.1/WebCore/dom/Document.cpp
+===================================================================
+--- webkit-1.2.1.orig/WebCore/dom/Document.cpp	2010-05-13 16:31:30.000000000 -0400
++++ webkit-1.2.1/WebCore/dom/Document.cpp	2010-06-28 21:48:38.000000000 -0400
+@@ -2879,6 +2879,28 @@
+     }
+ }
+ 
++void Document::nodeChildrenWillBeRemoved(ContainerNode* container)
++{
++    if (!disableRangeMutation(page())) {
++        HashSet<Range*>::const_iterator end = m_ranges.end();
++        for (HashSet<Range*>::const_iterator it = m_ranges.begin(); it != end; ++it)
++            (*it)->nodeChildrenWillBeRemoved(container);
++    }
++
++    HashSet<NodeIterator*>::const_iterator nodeIteratorsEnd = m_nodeIterators.end();
++    for (HashSet<NodeIterator*>::const_iterator it = m_nodeIterators.begin(); it != nodeIteratorsEnd; ++it) {
++        for (Node* n = container->firstChild(); n; n = n->nextSibling())
++            (*it)->nodeWillBeRemoved(n);
++    }
++
++    if (Frame* frame = this->frame()) {
++        for (Node* n = container->firstChild(); n; n = n->nextSibling()) {
++            frame->selection()->nodeWillBeRemoved(n);
++            frame->dragCaretController()->nodeWillBeRemoved(n);
++        }
++    }
++}
++
+ void Document::nodeWillBeRemoved(Node* n)
+ {
+     HashSet<NodeIterator*>::const_iterator nodeIteratorsEnd = m_nodeIterators.end();
+Index: webkit-1.2.1/WebCore/dom/ContainerNode.cpp
+===================================================================
+--- webkit-1.2.1.orig/WebCore/dom/ContainerNode.cpp	2010-05-13 16:31:30.000000000 -0400
++++ webkit-1.2.1/WebCore/dom/ContainerNode.cpp	2010-06-28 21:48:38.000000000 -0400
+@@ -292,19 +292,32 @@
+     Node::willRemove();
+ }
+ 
+-static ExceptionCode willRemoveChild(Node *child)
++static void willRemoveChild(Node* child)
+ {
+-    ExceptionCode ec = 0;
++    // update auxiliary doc info (e.g. iterators) to note that node is being removed
++    child->document()->nodeWillBeRemoved(child);
++    child->document()->incDOMTreeVersion();
+ 
+     // fire removed from document mutation events.
+     dispatchChildRemovalEvents(child);
+-    if (ec)
+-        return ec;
+ 
+     if (child->attached())
+         child->willRemove();
+-    
+-    return 0;
++}
++
++static void willRemoveChildren(ContainerNode* container)
++{
++    container->document()->nodeChildrenWillBeRemoved(container);
++    container->document()->incDOMTreeVersion();
++
++    // FIXME: Adding new children from event handlers can cause an infinite loop here.
++    for (RefPtr<Node> child = container->firstChild(); child; child = child->nextSibling()) {
++        // fire removed from document mutation events.
++        dispatchChildRemovalEvents(child.get());
++
++        if (child->attached())
++            child->willRemove();
++    }
+ }
+ 
+ bool ContainerNode::removeChild(Node* oldChild, ExceptionCode& ec)
+@@ -328,10 +341,7 @@
+     }
+ 
+     RefPtr<Node> child = oldChild;
+-
+-    ec = willRemoveChild(child.get());
+-    if (ec)
+-        return false;
++    willRemoveChild(child.get());
+ 
+     // Mutation events might have moved this child into a different parent.
+     if (child->parentNode() != this) {
+@@ -399,14 +409,12 @@
+         return false;
+ 
+     // The container node can be removed from event handlers.
+-    RefPtr<Node> protect(this);
+-    
++    RefPtr<ContainerNode> protect(this);
++
+     // Do any prep work needed before actually starting to detach
+     // and remove... e.g. stop loading frames, fire unload events.
+-    // FIXME: Adding new children from event handlers can cause an infinite loop here.
+-    for (RefPtr<Node> n = m_firstChild; n; n = n->nextSibling())
+-        willRemoveChild(n.get());
+-    
++    willRemoveChildren(protect.get());
++
+     // exclude this node when looking for removed focusedNode since only children will be removed
+     document()->removeFocusedNodeOfSubtree(this, true);
+ 
+@@ -936,6 +944,8 @@
+ 
+ static void dispatchChildRemovalEvents(Node* child)
+ {
++    ASSERT(!eventDispatchForbidden());
++
+ #if ENABLE(INSPECTOR)    
+     if (Page* page = child->document()->page()) {
+         if (InspectorController* inspectorController = page->inspectorController())
+@@ -946,11 +956,6 @@
+     RefPtr<Node> c = child;
+     RefPtr<Document> document = child->document();
+ 
+-    // update auxiliary doc info (e.g. iterators) to note that node is being removed
+-    document->nodeWillBeRemoved(child);
+-
+-    document->incDOMTreeVersion();
+-
+     // dispatch pre-removal mutation events
+     if (c->parentNode() && document->hasListenerType(Document::DOMNODEREMOVED_LISTENER))
+         c->dispatchEvent(MutationEvent::create(eventNames().DOMNodeRemovedEvent, true, c->parentNode()));
+Index: webkit-1.2.1/WebCore/dom/Range.h
+===================================================================
+--- webkit-1.2.1.orig/WebCore/dom/Range.h	2010-05-13 16:31:30.000000000 -0400
++++ webkit-1.2.1/WebCore/dom/Range.h	2010-06-28 21:48:38.000000000 -0400
+@@ -111,6 +111,7 @@
+     void textQuads(Vector<FloatQuad>&, bool useSelectionHeight = false);
+ 
+     void nodeChildrenChanged(ContainerNode*);
++    void nodeChildrenWillBeRemoved(ContainerNode*);
+     void nodeWillBeRemoved(Node*);
+ 
+     void textInserted(Node*, unsigned offset, unsigned length);
+Index: webkit-1.2.1/WebCore/dom/Range.cpp
+===================================================================
+--- webkit-1.2.1.orig/WebCore/dom/Range.cpp	2010-05-13 16:31:30.000000000 -0400
++++ webkit-1.2.1/WebCore/dom/Range.cpp	2010-06-28 21:48:38.000000000 -0400
+@@ -1716,6 +1716,31 @@
+     boundaryNodeChildrenChanged(m_end, container);
+ }
+ 
++static inline void boundaryNodeChildrenWillBeRemoved(RangeBoundaryPoint& boundary, ContainerNode* container)
++{
++    for (Node* nodeToBeRemoved = container->firstChild(); nodeToBeRemoved; nodeToBeRemoved = nodeToBeRemoved->nextSibling()) {
++        if (boundary.childBefore() == nodeToBeRemoved) {
++            boundary.setToStartOfNode(container);
++            return;
++        }
++
++        for (Node* n = boundary.container(); n; n = n->parentNode()) {
++            if (n == nodeToBeRemoved) {
++                boundary.setToStartOfNode(container);
++                return;
++            }
++        }
++    }
++}
++
++void Range::nodeChildrenWillBeRemoved(ContainerNode* container)
++{
++    ASSERT(container);
++    ASSERT(container->document() == m_ownerDocument);
++    boundaryNodeChildrenWillBeRemoved(m_start, container);
++    boundaryNodeChildrenWillBeRemoved(m_end, container);
++}
++
+ static inline void boundaryNodeWillBeRemoved(RangeBoundaryPoint& boundary, Node* nodeToBeRemoved)
+ {
+     if (boundary.childBefore() == nodeToBeRemoved) {
diff --git a/debian/patches/series b/debian/patches/series
index e30cb0f..2eb6316 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -16,3 +16,4 @@ cve-2010-1422.patch
 cve-2010-1421.patch
 cve-2010-1501+1767.patch
 cve-2010-1664.patch
+cve-2010-1758.patch

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list