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

--- xorg-server-1.8.0/dix/window.c.orig	2010-08-07 17:45:14.000000000 +0200
+++ xorg-server-1.8.0/dix/window.c	2010-08-07 17:52:58.000000000 +0200
@@ -546,6 +546,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 
@@ -566,6 +608,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;
 
@@ -2457,6 +2504,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