--- 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);