>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