forked from pool/xorg-x11-server
Stefan Dirsch
d28145e2c5
CVE-2010-2240-tree_depth_limit.patch * xorg stack/heap overlap fix (bnc #618152) OBS-URL: https://build.opensuse.org/package/show/X11:XOrg/xorg-x11-server?expand=0&rev=278
74 lines
1.7 KiB
Diff
74 lines
1.7 KiB
Diff
--- 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);
|