File CVE-2010-2240-tree_depth_limit.patch of Package xorg-x11-server.import4546

--- xorg-server-1.9.0/dix/window.c.orig	2010-08-23 16:07:24.000000000 +0200
+++ xorg-server-1.9.0/dix/window.c	2010-08-23 16:14:09.000000000 +0200
@@ -535,6 +535,48 @@ RealChildHead(WindowPtr pWin)
 	return NullWindow;
 }
 
+static int
+TreeDepth(WindowPtr pWin)
+{
+    int depth = 1;
+    int max_depth = 1;
+    WindowPtr pChild;
+
+    if (!(pChild = pWin))
+	return 0;
+    while (1)
+    {
+	if (pChild->firstChild)
+	{
+	    ++depth;
+	    pChild = pChild->firstChild;
+	    continue;
+	} else if (depth > max_depth)
+	    max_depth = depth;
+	while (!pChild->nextSib && (pChild != pWin)) {
+	    --depth;
+	    pChild = pChild->parent;
+	}
+	if (pChild == pWin)
+	    break;
+	    pChild = pChild->nextSib;
+    }
+    return max_depth;
+}
+
+static int
+WindowDepth(WindowPtr pWin)
+{
+    int depth = 0;
+    while (pWin) {
+	++depth;
+	pWin = pWin->parent;
+    }
+    return depth;
+}
+
+#define MAX_TREE_DEPTH 256
+
 /*****
  * CreateWindow
  *    Makes a window in response to client request 
@@ -555,6 +597,11 @@ CreateWindow(Window wid, WindowPtr pPare
     PixmapFormatRec *format;
     WindowOptPtr ancwopt;
 
+    if (WindowDepth(pParent) >= MAX_TREE_DEPTH - 1) {
+	*error = BadAlloc;
+	return NullWindow;
+    }
+
     if (class == CopyFromParent)
 	class = pParent->drawable.class;
 
@@ -2434,6 +2481,9 @@ ReparentWindow(WindowPtr pWin, WindowPtr
     int bw = wBorderWidth (pWin);
     ScreenPtr pScreen;
 
+    if (WindowDepth(pParent) + TreeDepth(pWin) >= MAX_TREE_DEPTH)
+	return BadAlloc;
+
     pScreen = pWin->drawable.pScreen;
     if (TraverseTree(pWin, CompareWIDs, (pointer)&pParent->drawable.id) == WT_STOPWALKING)
 	return BadMatch;
openSUSE Build Service is sponsored by