- CVE-2010-2240-address_space_limit.patch/

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
This commit is contained in:
Stefan Dirsch 2010-08-17 15:29:05 +00:00 committed by Git OBS Bridge
parent 73e58bd3b6
commit d28145e2c5
4 changed files with 205 additions and 0 deletions

View File

@ -0,0 +1,121 @@
>From fedf91eeabcfdd6d26b52529a16a64f744aa42ad Mon Sep 17 00:00:00 2001
From: Matthieu Herrb <matthieu.herrb@laas.fr>
Date: Mon, 28 Jun 2010 23:54:13 +0200
Subject: [PATCH] Workaround for CVE-2010-2240.
By limiting the address space that the X server can use,
it prevents stack and mmap()ed areas to become so close that
the stack will grow over a mmaped area.
Credits: Rafal Wojtczuk <rafal@invisiblethingslab.com>
---
doc/Xserver.man.pre | 7 +++++++
include/opaque.h | 3 +++
os/osinit.c | 24 ++++++++++++++++++++++++
os/utils.c | 16 ++++++++++++++++
4 files changed, 50 insertions(+), 0 deletions(-)
diff --git a/doc/Xserver.man.pre b/doc/Xserver.man.pre
index ce3b3a1..91c595f 100644
--- a/doc/Xserver.man.pre
+++ b/doc/Xserver.man.pre
@@ -285,6 +285,13 @@ sets the stack space limit of the server to the specified number of kilobytes.
A value of zero makes the stack size as large as possible. The default value
of \-1 leaves the stack space limit unchanged.
.TP 8
+.B \-la \fIkilobytes\fP
+sets the address space limit of the server to the specified number of
+kilobytes.
+A value of zero makes address space as large as possible.
+The default value is 1572864 (1.5GB) on 32 bit architectures and
+10485760 (10GB) on 64 bit architectures.
+.TP 8
.B \-logo
turns on the X Window System logo display in the screen-saver.
There is currently no way to change this from a client.
diff --git a/include/opaque.h b/include/opaque.h
index b3c7c70..4208d03 100644
--- a/include/opaque.h
+++ b/include/opaque.h
@@ -67,6 +67,9 @@ extern _X_EXPORT int limitStackSpace;
#ifdef RLIMIT_NOFILE
extern _X_EXPORT int limitNoFile;
#endif
+#ifdef RLIMIT_AS
+extern _X_EXPORT int limitAddressSpace;
+#endif
extern _X_EXPORT Bool defeatAccessControl;
extern _X_EXPORT long maxBigRequestSize;
extern _X_EXPORT Bool party_like_its_1989;
diff --git a/os/osinit.c b/os/osinit.c
index 32747df..723fb14 100644
--- a/os/osinit.c
+++ b/os/osinit.c
@@ -96,6 +96,14 @@ int limitStackSpace = -1;
#ifdef RLIMIT_NOFILE
int limitNoFile = -1;
#endif
+#ifdef RLIMIT_AS
+#ifdef _XSERVER64
+#define XORG_AS_LIMIT 10737418240LL
+#else
+#define XORG_AS_LIMIT 1610612736
+#endif
+long limitAddressSpace = XORG_AS_LIMIT;
+#endif
static OsSigWrapperPtr OsSigWrapper = NULL;
@@ -301,6 +309,22 @@ OsInit(void)
}
}
#endif
+#ifdef RLIMIT_AS
+ if (limitAddressSpace >= 0)
+ {
+ struct rlimit rlim;
+
+ if (!getrlimit(RLIMIT_AS, &rlim))
+ {
+ if ((limitAddressSpace > 0)
+ && (limitAddressSpace < rlim.rlim_max))
+ rlim.rlim_cur = limitAddressSpace;
+ else
+ rlim.rlim_cur = rlim.rlim_max;
+ (void)setrlimit(RLIMIT_AS, &rlim);
+ }
+ }
+#endif
LockServer();
been_here = TRUE;
}
diff --git a/os/utils.c b/os/utils.c
index 51455cc..4af0cb3 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -745,6 +745,22 @@ ProcessCommandLine(int argc, char *argv[])
UseMsg();
}
#endif
+#ifdef RLIMIT_AS
+ else if ( strcmp( argv[i], "-la") == 0)
+ {
+ if (getuid() != geteuid()) {
+ FatalError("The '-la' option can only be used by root.\n");
+ }
+ if(++i < argc)
+ {
+ limitAddressSpace = atol(argv[i]);
+ if (limitAddressSpace > 0)
+ limitAddressSpace *= 1024;
+ }
+ else
+ UseMsg();
+ }
+#endif
else if ( strcmp ( argv[i], "-nolock") == 0)
{
#if !defined(WIN32) && !defined(__CYGWIN__)
--
1.7.0.5

View File

@ -0,0 +1,73 @@
--- 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);

View File

@ -1,3 +1,10 @@
-------------------------------------------------------------------
Tue Aug 17 17:23:45 CEST 2010 - sndirsch@suse.de
- CVE-2010-2240-address_space_limit.patch/
CVE-2010-2240-tree_depth_limit.patch
* xorg stack/heap overlap fix (bnc #618152)
-------------------------------------------------------------------
Mon Aug 16 12:50:39 CEST 2010 - sndirsch@suse.de

View File

@ -118,6 +118,8 @@ Patch213: xorg-server-xdmcp.patch
Patch214: xorg-x11-server-gl-apps-crash.patch
Patch215: xorg-server-revert-event-mask.patch
Patch216: xorg-server-commit-21ed660.diff
Patch217: CVE-2010-2240-address_space_limit.patch
Patch218: CVE-2010-2240-tree_depth_limit.patch
%if %moblin
Patch300: moblin-use_preferred_mode_for_all_outputs.diff
%endif
@ -246,6 +248,8 @@ popd
%patch214 -p1
%patch215 -p1
%patch216 -p1
%patch217 -p1
%patch218 -p1
%if %moblin
%patch300 -p1
%endif