diff --git a/CVE-2010-2240-address_space_limit.patch b/CVE-2010-2240-address_space_limit.patch new file mode 100644 index 0000000..69718a9 --- /dev/null +++ b/CVE-2010-2240-address_space_limit.patch @@ -0,0 +1,121 @@ +>From fedf91eeabcfdd6d26b52529a16a64f744aa42ad Mon Sep 17 00:00:00 2001 +From: Matthieu Herrb +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 +--- + 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 + diff --git a/CVE-2010-2240-tree_depth_limit.patch b/CVE-2010-2240-tree_depth_limit.patch new file mode 100644 index 0000000..ccd687c --- /dev/null +++ b/CVE-2010-2240-tree_depth_limit.patch @@ -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); diff --git a/xorg-server-commit-21ed660.diff b/xorg-server-commit-21ed660.diff new file mode 100644 index 0000000..7acb66c --- /dev/null +++ b/xorg-server-commit-21ed660.diff @@ -0,0 +1,32 @@ +commit 21ed660f30a3f96c787ab00a16499e0fb034b2ad +Author: Chris Humbert +Date: Fri May 7 17:02:43 2010 +1000 + + dix: make DeviceEvent coordinates signed for Xinerama. #24986 + + With Xinerama enabled, event coordinates are relative to Screen 0, so + they can be negative. The new DeviceEvent's coordinates are of type + uint16_t, making screens above and to the left of Screen 0 unusable. + + X.Org Bug 24986 + + Signed-off-by: Chris Humbert + Reviewed-by: Peter Hutterer + Signed-off-by: Keith Packard + +diff --git a/include/eventstr.h b/include/eventstr.h +index 79685c1..433227e 100644 +--- a/include/eventstr.h ++++ b/include/eventstr.h +@@ -91,9 +91,9 @@ struct _DeviceEvent + uint32_t button; /**< Button number */ + uint32_t key; /**< Key code */ + } detail; +- uint16_t root_x; /**< Pos relative to root window in integral data */ ++ int16_t root_x; /**< Pos relative to root window in integral data */ + float root_x_frac; /**< Pos relative to root window in frac part */ +- uint16_t root_y; /**< Pos relative to root window in integral part */ ++ int16_t root_y; /**< Pos relative to root window in integral part */ + float root_y_frac; /**< Pos relative to root window in frac part */ + uint8_t buttons[(MAX_BUTTONS + 7)/8]; /**< Button mask */ + struct { diff --git a/xorg-server-xdmcp.patch b/xorg-server-xdmcp.patch index c7e0641..840c271 100644 --- a/xorg-server-xdmcp.patch +++ b/xorg-server-xdmcp.patch @@ -1,245 +1,28 @@ ---- xorg-server-1.8.0/os/access.c 2009-12-17 05:58:44.000000000 +0000 -+++ xorg-server-1.8.0-20100708/os/access.c 2010-07-08 13:55:08.000000000 +0000 -@@ -800,18 +800,6 @@ - ) - continue; +--- xorg-server-1.6.5/os/access.c ++++ xorg-server-1.6.5/os/access.c +@@ -781,7 +781,9 @@ -- /* -- * ignore 'localhost' entries as they're not useful + /* + * ignore 'localhost' entries as they're not useful - * on the other end of the wire -- */ -- if (ifr->ifa_flags & IFF_LOOPBACK) -- continue; -- -- if (family == FamilyInternet && -- addr[0] == 127 && addr[1] == 0 && -- addr[2] == 0 && addr[3] == 1) -- continue; -- - /* - * Ignore '0.0.0.0' entries as they are - * returned by some OSes for unconfigured NICs but they are -@@ -821,11 +809,6 @@ - addr[0] == 0 && addr[1] == 0 && - addr[2] == 0 && addr[3] == 0) ++ * on the other end of the wire and because on hosts ++ * with shared home dirs they'll result in conflic ++ * entries in ~/.Xauthority + */ + if (ifr->ifa_flags & IFF_LOOPBACK) + continue; +@@ -804,6 +806,14 @@ + else if (family == FamilyInternet6 && + IN6_IS_ADDR_LOOPBACK((struct in6_addr *)addr)) continue; --#if defined(IPv6) && defined(AF_INET6) -- else if (family == FamilyInternet6 && -- IN6_IS_ADDR_LOOPBACK((struct in6_addr *)addr)) -- continue; --#endif ++ ++ /* Ignore IPv6 link local addresses (fe80::/10), because ++ * they need a scope identifier, which we have no way ++ * of telling to the other end. ++ */ ++ if (family == FamilyInternet6 && ++ IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)addr)) ++ continue; + #endif XdmcpRegisterConnection(family, (char *)addr, len); #if defined(IPv6) && defined(AF_INET6) - if (family == FamilyInternet6) ---- xorg-server-1.8.0/os/xdmcp.c 2009-11-04 16:25:50.000000000 +0000 -+++ xorg-server-1.8.0-20100708/os/xdmcp.c 2010-07-08 13:56:36.000000000 +0000 -@@ -27,6 +27,7 @@ - #include - #include - #include -+#include - #include - #endif - -@@ -209,6 +210,50 @@ - - static ARRAY8 ManufacturerDisplayID; - -+ -+ -+static int is_loopback(int type, void *a) -+{ -+ char *addr = a; -+ int ret = 0; -+ int gairet; -+ struct sockaddr_storage s; -+ struct sockaddr_in *s4 = (struct sockaddr_in *)&s; -+ struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)&s; -+ char host[NI_MAXHOST]; -+ -+ memset(&s, 0, sizeof(s)); -+ if (type == FamilyInternet) { -+ s4->sin_family = AF_INET; -+ s4->sin_addr.s_addr = *((in_addr_t*)a); -+ if (addr[0] == 127) { -+ /* IPv4 loopback /8 net */ -+ ret = 1; -+ } -+ } else if (type == FamilyInternet6) { -+ s6->sin6_family = AF_INET6; -+ memcpy(&(s6->sin6_addr), a, sizeof(struct in6_addr)); -+ if (IN6_IS_ADDR_LOOPBACK(addr)) { -+ /* IPv6 loopback address */ -+ ret = 1; -+ } else if (IN6_IS_ADDR_V4MAPPED(addr) && -+ ((struct in6_addr*)addr)->s6_addr[12] == 127) { -+ /* IPv4 mapped loopback address */ -+ ret = 1; -+ } -+ } else { -+ return 0; -+ } -+ gairet = getnameinfo((struct sockaddr*)&s, sizeof(struct sockaddr_storage), -+ host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); -+ if (gairet != 0) { -+ ErrorF(" => %s\n", gai_strerror(gairet)); -+ } else { -+ ErrorF("is_loopback(%s) = %d\n", host, ret); -+ } -+ return ret; -+} -+ - static void - XdmcpRegisterManufacturerDisplayID (char *name, int length) - { -@@ -438,8 +483,8 @@ - * Register the host address for the display - */ - --static ARRAY16 ConnectionTypes; --static ARRAYofARRAY8 ConnectionAddresses; -+static ARRAY16 ConnectionTypes[2]; -+static ARRAYofARRAY8 ConnectionAddresses[2]; - static long xdmcpGeneration; - - void -@@ -451,12 +496,21 @@ - int i; - CARD8 *newAddress; - -+ /* -+ * Index for ConnectionTypes and ConnectionAddresses: -+ * 1 for loopback address, 0 for remote addresses. -+ */ -+ int l; -+ - if (xdmcpGeneration != serverGeneration) - { -- XdmcpDisposeARRAY16 (&ConnectionTypes); -- XdmcpDisposeARRAYofARRAY8 (&ConnectionAddresses); -+ XdmcpDisposeARRAY16 (&ConnectionTypes[0]); -+ XdmcpDisposeARRAY16 (&ConnectionTypes[1]); -+ XdmcpDisposeARRAYofARRAY8 (&ConnectionAddresses[0]); -+ XdmcpDisposeARRAYofARRAY8 (&ConnectionAddresses[1]); - xdmcpGeneration = serverGeneration; - } -+ l = is_loopback(type, address); - if (xdm_from != NULL) { /* Only register the requested address */ - const void *regAddr = address; - const void *fromAddr = NULL; -@@ -490,27 +544,27 @@ - return; - } - } -- if (ConnectionAddresses.length + 1 == 256) -+ if (ConnectionAddresses[l].length + 1 == 256) - return; - newAddress = xalloc (addrlen * sizeof (CARD8)); - if (!newAddress) - return; -- if (!XdmcpReallocARRAY16 (&ConnectionTypes, ConnectionTypes.length + 1)) -+ if (!XdmcpReallocARRAY16 (&ConnectionTypes[l], ConnectionTypes[l].length + 1)) - { - xfree (newAddress); - return; - } -- if (!XdmcpReallocARRAYofARRAY8 (&ConnectionAddresses, -- ConnectionAddresses.length + 1)) -+ if (!XdmcpReallocARRAYofARRAY8 (&ConnectionAddresses[l], -+ ConnectionAddresses[l].length + 1)) - { - xfree (newAddress); - return; - } -- ConnectionTypes.data[ConnectionTypes.length - 1] = (CARD16) type; -+ ConnectionTypes[l].data[ConnectionTypes[l].length - 1] = (CARD16) type; - for (i = 0; i < addrlen; i++) - newAddress[i] = address[i]; -- ConnectionAddresses.data[ConnectionAddresses.length-1].data = newAddress; -- ConnectionAddresses.data[ConnectionAddresses.length-1].length = addrlen; -+ ConnectionAddresses[l].data[ConnectionAddresses[l].length-1].data = newAddress; -+ ConnectionAddresses[l].data[ConnectionAddresses[l].length-1].length = addrlen; - } - - /* -@@ -1176,12 +1230,19 @@ - CARD16 XdmcpConnectionType; - ARRAY8 authenticationData; - int socketfd = xdmcpSocket; -+ int l; - - switch (SOCKADDR_FAMILY(ManagerAddress)) - { -- case AF_INET: XdmcpConnectionType=FamilyInternet; break; -+ case AF_INET: -+ XdmcpConnectionType=FamilyInternet; -+ l = is_loopback(XdmcpConnectionType, &(((struct sockaddr_in*)&ManagerAddress)->sin_addr.s_addr)); -+ break; - #if defined(IPv6) && defined(AF_INET6) -- case AF_INET6: XdmcpConnectionType=FamilyInternet6; break; -+ case AF_INET6: -+ XdmcpConnectionType=FamilyInternet6; -+ l = is_loopback(XdmcpConnectionType, ((struct sockaddr_in6*)&ManagerAddress)->sin6_addr.s6_addr); -+ break; - #endif - default: XdmcpConnectionType=0xffff; break; - } -@@ -1190,10 +1251,10 @@ - header.opcode = (CARD16) REQUEST; - - length = 2; /* display number */ -- length += 1 + 2 * ConnectionTypes.length; /* connection types */ -+ length += 1 + 2 * ConnectionTypes[l].length; /* connection types */ - length += 1; /* connection addresses */ -- for (i = 0; i < ConnectionAddresses.length; i++) -- length += 2 + ConnectionAddresses.data[i].length; -+ for (i = 0; i < ConnectionAddresses[l].length; i++) -+ length += 2 + ConnectionAddresses[l].data[i].length; - authenticationData.length = 0; - authenticationData.data = 0; - if (AuthenticationFuncs) -@@ -1216,27 +1277,27 @@ - return; - } - XdmcpWriteCARD16 (&buffer, DisplayNumber); -- XdmcpWriteCARD8 (&buffer, ConnectionTypes.length); -+ XdmcpWriteCARD8 (&buffer, ConnectionTypes[l].length); - - /* The connection array is send reordered, so that connections of */ - /* the same address type as the XDMCP manager connection are send */ - /* first. This works around a bug in xdm. mario@klebsch.de */ -- for (i = 0; i < (int)ConnectionTypes.length; i++) -- if (ConnectionTypes.data[i]==XdmcpConnectionType) -- XdmcpWriteCARD16 (&buffer, ConnectionTypes.data[i]); -- for (i = 0; i < (int)ConnectionTypes.length; i++) -- if (ConnectionTypes.data[i]!=XdmcpConnectionType) -- XdmcpWriteCARD16 (&buffer, ConnectionTypes.data[i]); -- -- XdmcpWriteCARD8 (&buffer, ConnectionAddresses.length); -- for (i = 0; i < (int)ConnectionAddresses.length; i++) -- if ( (i=ConnectionTypes.length) || -- (ConnectionTypes.data[i]!=XdmcpConnectionType) ) -- XdmcpWriteARRAY8 (&buffer, &ConnectionAddresses.data[i]); -+ for (i = 0; i < (int)ConnectionTypes[l].length; i++) -+ if (ConnectionTypes[l].data[i]==XdmcpConnectionType) -+ XdmcpWriteCARD16 (&buffer, ConnectionTypes[l].data[i]); -+ for (i = 0; i < (int)ConnectionTypes[l].length; i++) -+ if (ConnectionTypes[l].data[i]!=XdmcpConnectionType) -+ XdmcpWriteCARD16 (&buffer, ConnectionTypes[l].data[i]); -+ -+ XdmcpWriteCARD8 (&buffer, ConnectionAddresses[l].length); -+ for (i = 0; i < (int)ConnectionAddresses[l].length; i++) -+ if ( (i=ConnectionTypes[l].length) || -+ (ConnectionTypes[l].data[i]!=XdmcpConnectionType) ) -+ XdmcpWriteARRAY8 (&buffer, &ConnectionAddresses[l].data[i]); - - XdmcpWriteARRAY8 (&buffer, AuthenticationName); - XdmcpWriteARRAY8 (&buffer, &authenticationData); diff --git a/xorg-x11-server.changes b/xorg-x11-server.changes index b41ac11..d77d782 100644 --- a/xorg-x11-server.changes +++ b/xorg-x11-server.changes @@ -1,3 +1,23 @@ +------------------------------------------------------------------- +Thu Aug 19 15:53:11 CEST 2010 - max@suse.de + +- Replaced the previous xdmcp fix with a simpler approach that + doesn't cause login problems in xdm and kdm. (bnc#625593) + +------------------------------------------------------------------- +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 + +- xorg-server-commit-21ed660.diff + * dix: make DeviceEvent coordinates signed for Xinerama + (bnc #628295, bfo #24986) + ------------------------------------------------------------------- Tue Aug 10 20:56:13 CEST 2010 - sndirsch@suse.de diff --git a/xorg-x11-server.spec b/xorg-x11-server.spec index b805149..95fe376 100644 --- a/xorg-x11-server.spec +++ b/xorg-x11-server.spec @@ -32,7 +32,7 @@ BuildRequires: libjpeg-devel %endif Url: http://xorg.freedesktop.org/ Version: 7.5_%{dirsuffix} -Release: 15 +Release: 16 License: GPLv2+ ; MIT License (or similar) BuildRoot: %{_tmppath}/%{name}-%{version}-build Group: System/X11/Servers/XF86_4 @@ -117,6 +117,9 @@ Patch212: dmx-silly.patch 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 @@ -244,6 +247,9 @@ popd %patch213 -p1 %patch214 -p1 %patch215 -p1 +%patch216 -p1 +%patch217 -p1 +%patch218 -p1 %if %moblin %patch300 -p1 %endif