From edd2cac9fa05fdd0eceee3dd571f753acb9012ba Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Tue, 10 Jun 2008 12:23:03 -0600 Subject: [PATCH 01/12] CVE-2008-2362 - RENDER Extension memory corruption Integer overflows can occur in the code validating the parameters for the SProcRenderCreateLinearGradient, SProcRenderCreateRadialGradient and SProcRenderCreateConicalGradient functions, leading to memory corruption by swapping bytes outside of the intended request parameters. (cherry picked from commit 9171206db349a0c6fda719746be0b15049d57aaa) --- render/render.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/render/render.c b/render/render.c index f03f54a2b..c6d55daa8 100644 --- a/render/render.c +++ b/render/render.c @@ -1987,6 +1987,8 @@ static int ProcRenderCreateLinearGradient (ClientPtr client) LEGAL_NEW_RESOURCE(stuff->pid, client); len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq); + if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor))) return BadLength; @@ -2575,18 +2577,18 @@ SProcRenderCreateSolidFill(ClientPtr client) return (*ProcRenderVector[stuff->renderReqType]) (client); } -static void swapStops(void *stuff, int n) +static void swapStops(void *stuff, int num) { - int i; + int i, n; CARD32 *stops; CARD16 *colors; stops = (CARD32 *)(stuff); - for (i = 0; i < n; ++i) { + for (i = 0; i < num; ++i) { swapl(stops, n); ++stops; } colors = (CARD16 *)(stops); - for (i = 0; i < 4*n; ++i) { + for (i = 0; i < 4*num; ++i) { swaps(stops, n); ++stops; } @@ -2609,6 +2611,8 @@ SProcRenderCreateLinearGradient (ClientPtr client) swapl(&stuff->nStops, n); len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq); + if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor))) return BadLength; @@ -2636,6 +2640,8 @@ SProcRenderCreateRadialGradient (ClientPtr client) swapl(&stuff->nStops, n); len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq); + if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor))) return BadLength; @@ -2660,6 +2666,8 @@ SProcRenderCreateConicalGradient (ClientPtr client) swapl(&stuff->nStops, n); len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq); + if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor))) return BadLength; From b251fdd9d90532871b2a2b2f44a64b0e769fe3fc Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Tue, 10 Jun 2008 12:22:30 -0600 Subject: [PATCH 02/12] CVE-2008-2361 - RENDER Extension crash An integer overflow may occur in the computation of the size of the glyph to be allocated by the ProcRenderCreateCursor() function which will cause less memory to be allocated than expected, leading later to dereferencing un-mapped memory, causing a crash of the X server. (cherry picked from commit 5257a0f83d5f3d80d0cd44dd76d047bac3869592) --- render/render.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/render/render.c b/render/render.c index c6d55daa8..40b8439c6 100644 --- a/render/render.c +++ b/render/render.c @@ -1562,6 +1562,8 @@ ProcRenderCreateCursor (ClientPtr client) pScreen = pSrc->pDrawable->pScreen; width = pSrc->pDrawable->width; height = pSrc->pDrawable->height; + if (height && width > UINT32_MAX/(height*sizeof(CARD32))) + return BadAlloc; if ( stuff->x > width || stuff->y > height ) return (BadMatch); From 69b173c6997954277dbd23eecc2cbf74e74ab228 Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Tue, 10 Jun 2008 12:21:26 -0600 Subject: [PATCH 03/12] CVE-2008-2360 - RENDER Extension heap buffer overflow An integer overflow may occur in the computation of the size of the glyph to be allocated by the AllocateGlyph() function which will cause less memory to be allocated than expected, leading to later heap overflow. (cherry picked from commit c5f69b297b1227cb802394fa90efdbe1de607f3c) --- render/render.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/render/render.c b/render/render.c index 40b8439c6..638aa46a3 100644 --- a/render/render.c +++ b/render/render.c @@ -1117,9 +1117,16 @@ ProcRenderAddGlyphs (ClientPtr client) remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs; for (i = 0; i < nglyphs; i++) { + size_t padded_width; glyph_new = &glyphs[i]; - size = gi[i].height * PixmapBytePad (gi[i].width, - glyphSet->format->depth); + + padded_width = PixmapBytePad (gi[i].width, + glyphSet->format->depth); + + if (gi[i].height && padded_width > (UINT32_MAX - sizeof(GlyphRec))/gi[i].height) + break; + + size = gi[i].height * padded_width; if (remain < size) break; From e83c79701f0abc081f1b127785d5502e2e48f905 Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Tue, 10 Jun 2008 12:20:43 -0600 Subject: [PATCH 04/12] CVE-2008-1379 - MIT-SHM arbitrary memory read An integer overflow in the validation of the parameters of the ShmPutImage() request makes it possible to trigger the copy of arbitrary server memory to a pixmap that can subsequently be read by the client, to read arbitrary parts of the X server memory space. (cherry picked from commit 063f18ef6d7bf834225ddfd3527e58c078628f5f) --- Xext/shm.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Xext/shm.c b/Xext/shm.c index b2973bff6..8cf59443c 100644 --- a/Xext/shm.c +++ b/Xext/shm.c @@ -894,8 +894,17 @@ ProcShmPutImage(client) return BadValue; } - VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight, - client); + /* + * There's a potential integer overflow in this check: + * VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight, + * client); + * the version below ought to avoid it + */ + if (stuff->totalHeight != 0 && + length > (shmdesc->size - stuff->offset)/stuff->totalHeight) { + client->errorValue = stuff->totalWidth; + return BadValue; + } if (stuff->srcX > stuff->totalWidth) { client->errorValue = stuff->srcX; From 626ea1b02dabc218f7f73adead8ee9b287d0648e Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Tue, 10 Jun 2008 12:20:00 -0600 Subject: [PATCH 05/12] CVE-2008-1377 - RECORD and Security extensions memory corruption Lack of validation of the parameters of the SProcSecurityGenerateAuthorization SProcRecordCreateContext functions makes it possible for a specially crafted request to trigger the swapping of bytes outside the parameter of these requests, causing memory corruption. (cherry picked from commit 95d162c4389857d960da9b0158345c1714e91f31) --- Xext/security.c | 10 +++++++--- record/record.c | 16 +++++++++++++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/Xext/security.c b/Xext/security.c index e82b97626..ad30e06b8 100644 --- a/Xext/security.c +++ b/Xext/security.c @@ -679,15 +679,19 @@ SProcSecurityGenerateAuthorization( register char n; CARD32 *values; unsigned long nvalues; + int values_offset; swaps(&stuff->length, n); REQUEST_AT_LEAST_SIZE(xSecurityGenerateAuthorizationReq); swaps(&stuff->nbytesAuthProto, n); swaps(&stuff->nbytesAuthData, n); swapl(&stuff->valueMask, n); - values = (CARD32 *)(&stuff[1]) + - ((stuff->nbytesAuthProto + (unsigned)3) >> 2) + - ((stuff->nbytesAuthData + (unsigned)3) >> 2); + values_offset = ((stuff->nbytesAuthProto + (unsigned)3) >> 2) + + ((stuff->nbytesAuthData + (unsigned)3) >> 2); + if (values_offset > + stuff->length - (sz_xSecurityGenerateAuthorizationReq >> 2)) + return BadLength; + values = (CARD32 *)(&stuff[1]) + values_offset; nvalues = (((CARD32 *)stuff) + stuff->length) - values; SwapLongs(values, nvalues); return ProcSecurityGenerateAuthorization(client); diff --git a/record/record.c b/record/record.c index debe3c472..5fb860c74 100644 --- a/record/record.c +++ b/record/record.c @@ -2657,7 +2657,7 @@ SProcRecordQueryVersion(ClientPtr client) } /* SProcRecordQueryVersion */ -static void +static int SwapCreateRegister(xRecordRegisterClientsReq *stuff) { register char n; @@ -2668,11 +2668,17 @@ SwapCreateRegister(xRecordRegisterClientsReq *stuff) swapl(&stuff->nClients, n); swapl(&stuff->nRanges, n); pClientID = (XID *)&stuff[1]; + if (stuff->nClients > stuff->length - (sz_xRecordRegisterClientsReq >> 2)) + return BadLength; for (i = 0; i < stuff->nClients; i++, pClientID++) { swapl(pClientID, n); } + if (stuff->nRanges > stuff->length - (sz_xRecordRegisterClientsReq >> 2) + - stuff->nClients) + return BadLength; RecordSwapRanges((xRecordRange *)pClientID, stuff->nRanges); + return Success; } /* SwapCreateRegister */ @@ -2680,11 +2686,13 @@ static int SProcRecordCreateContext(ClientPtr client) { REQUEST(xRecordCreateContextReq); + int status; register char n; swaps(&stuff->length, n); REQUEST_AT_LEAST_SIZE(xRecordCreateContextReq); - SwapCreateRegister((pointer)stuff); + if ((status = SwapCreateRegister((pointer)stuff)) != Success) + return status; return ProcRecordCreateContext(client); } /* SProcRecordCreateContext */ @@ -2693,11 +2701,13 @@ static int SProcRecordRegisterClients(ClientPtr client) { REQUEST(xRecordRegisterClientsReq); + int status; register char n; swaps(&stuff->length, n); REQUEST_AT_LEAST_SIZE(xRecordRegisterClientsReq); - SwapCreateRegister((pointer)stuff); + if ((status = SwapCreateRegister((pointer)stuff)) != Success) + return status; return ProcRecordRegisterClients(client); } /* SProcRecordRegisterClients */ From b4c5832c75164ad08bc43c37a214b90353653a38 Mon Sep 17 00:00:00 2001 From: Sascha Hlusiak Date: Tue, 25 Mar 2008 17:37:25 +0100 Subject: [PATCH 06/12] Support to pass arbitrary options via HAL hotplugging Parse "input.x11_options" and pass every key/name pair to the driver. Remove check for input.capabilities, because that's part of the fdi files. Thanks to Dustin Spicuzza for the patch. (cherry picked from commit 47eb658e802775021e3efec109f95431cca188ca) --- config/hal.c | 194 +++++++++++++++++++++++++------------------ config/x11-input.fdi | 62 ++++++++++++-- configure.ac | 2 + 3 files changed, 173 insertions(+), 85 deletions(-) diff --git a/config/hal.c b/config/hal.c index 6534408fa..f9cffdb4e 100644 --- a/config/hal.c +++ b/config/hal.c @@ -38,9 +38,10 @@ #include "config-backends.h" #include "os.h" -#define TYPE_NONE 0 -#define TYPE_KEYS 1 -#define TYPE_POINTER 2 + +#define LIBHAL_PROP_KEY "input.x11_options." +#define LIBHAL_XKB_PROP_KEY "input.xkb." + struct config_hal_info { DBusConnection *system_bus; @@ -50,7 +51,8 @@ struct config_hal_info { static void remove_device(DeviceIntPtr dev) { - DebugF("[config/hal] removing device %s\n", dev->name); + /* this only gets called for devices that have already been added */ + LogMessage(X_INFO, "config/hal: removing device %s\n", dev->name); /* Call PIE here so we don't try to dereference a device that's * already been removed. */ @@ -107,7 +109,7 @@ get_prop_string(LibHalContext *hal_ctx, const char *udi, const char *name) char *prop, *ret; prop = libhal_device_get_property_string(hal_ctx, udi, name, NULL); - DebugF("[config/hal] getting %s on %s returned %s\n", name, udi, prop); + LogMessageVerb(X_INFO, 10, "config/hal: getting %s on %s returned %s\n", name, udi, prop); if (prop) { ret = xstrdup(prop); libhal_free_string(prop); @@ -119,6 +121,9 @@ get_prop_string(LibHalContext *hal_ctx, const char *udi, const char *name) return ret; } +/* this function is no longer used... keep it here in case its needed in + * the future. */ +#if 0 static char * get_prop_string_array(LibHalContext *hal_ctx, const char *udi, const char *prop) { @@ -152,117 +157,146 @@ get_prop_string_array(LibHalContext *hal_ctx, const char *udi, const char *prop) return ret; } +#endif static void device_added(LibHalContext *hal_ctx, const char *udi) { - char **props; - char *path = NULL, *driver = NULL, *name = NULL, *xkb_rules = NULL; - char *xkb_model = NULL, *xkb_layout = NULL, *xkb_variant = NULL; - char *xkb_options = NULL, *config_info = NULL; + char *path = NULL, *driver = NULL, *name = NULL, *config_info = NULL; InputOption *options = NULL, *tmpo = NULL; DeviceIntPtr dev; DBusError error; - int type = TYPE_NONE; - int i; - + + LibHalPropertySet *set = NULL; + LibHalPropertySetIterator set_iter; + char *psi_key = NULL, *tmp_val, *tmp_key; + + dbus_error_init(&error); - props = libhal_device_get_property_strlist(hal_ctx, udi, - "info.capabilities", &error); - if (!props) { - DebugF("[config/hal] couldn't get capabilities for %s: %s (%s)\n", - udi, error.name, error.message); - goto out_error; - } - for (i = 0; props[i]; i++) { - /* input.keys is the new, of which input.keyboard is a subset, but - * input.keyboard is the old 'we have keys', so we have to keep it - * around. */ - if (strcmp(props[i], "input.keys") == 0 || - strcmp(props[i], "input.keyboard") == 0) - type |= TYPE_KEYS; - if (strcmp(props[i], "input.mouse") == 0 || - strcmp(props[i], "input.touchpad") == 0) - type |= TYPE_POINTER; - } - libhal_free_string_array(props); - - if (type == TYPE_NONE) - goto out_error; - driver = get_prop_string(hal_ctx, udi, "input.x11_driver"); - path = get_prop_string(hal_ctx, udi, "input.device"); - if (!driver || !path) { - DebugF("[config/hal] no driver or path specified for %s\n", udi); + if (!driver){ + /* verbose, don't tell the user unless they _want_ to see it */ + LogMessageVerb(X_INFO,7,"config/hal: no driver specified for device %s\n", udi); goto unwind; } + + path = get_prop_string(hal_ctx, udi, "input.device"); + if (!path) { + LogMessage(X_WARNING,"config/hal: no driver or path specified for %s\n", udi); + goto unwind; + } + name = get_prop_string(hal_ctx, udi, "info.product"); if (!name) name = xstrdup("(unnamed)"); - if (type & TYPE_KEYS) { - xkb_rules = get_prop_string(hal_ctx, udi, "input.xkb.rules"); - xkb_model = get_prop_string(hal_ctx, udi, "input.xkb.model"); - xkb_layout = get_prop_string(hal_ctx, udi, "input.xkb.layout"); - xkb_variant = get_prop_string(hal_ctx, udi, "input.xkb.variant"); - xkb_options = get_prop_string_array(hal_ctx, udi, "input.xkb.options"); - } - options = xcalloc(sizeof(*options), 1); + if (!options){ + LogMessage(X_ERROR, "config/hal: couldn't allocate space for input options!\n"); + goto unwind; + } + options->key = xstrdup("_source"); options->value = xstrdup("server/hal"); if (!options->key || !options->value) { - ErrorF("[config] couldn't allocate first key/value pair\n"); + LogMessage(X_ERROR, "config/hal: couldn't allocate first key/value pair\n"); goto unwind; } + /* most drivers use device.. not path. evdev uses both however, but the + * path version isn't documented apparently. support both for now. */ add_option(&options, "path", path); + add_option(&options, "device", path); + add_option(&options, "driver", driver); add_option(&options, "name", name); + config_info = xalloc(strlen(udi) + 5); /* "hal:" and NULL */ - if (!config_info) + if (!config_info) { + LogMessage(X_ERROR, "config/hal: couldn't allocate name\n"); goto unwind; + } sprintf(config_info, "hal:%s", udi); - if (xkb_rules) - add_option(&options, "xkb_rules", xkb_rules); - if (xkb_model) - add_option(&options, "xkb_model", xkb_model); - if (xkb_layout) - add_option(&options, "xkb_layout", xkb_layout); - if (xkb_variant) - add_option(&options, "xkb_variant", xkb_variant); - if (xkb_options) - add_option(&options, "xkb_options", xkb_options); + /* ok, grab options from hal.. iterate through all properties + * and lets see if any of them are options that we can add */ + set = libhal_device_get_all_properties(hal_ctx, udi, &error); + + if (!set) { + LogMessage(X_ERROR, "config/hal: couldn't get property list for %s: %s (%s)\n", + udi, error.name, error.message); + goto unwind; + } + + libhal_psi_init(&set_iter,set); + while (libhal_psi_has_more(&set_iter)) { + /* we are looking for supported keys.. extract and add to options */ + psi_key = libhal_psi_get_key(&set_iter); + + if (psi_key){ - DebugF("[config/hal] Adding device %s\n", name); + /* normal options first (input.x11_options.) */ + if (!strncasecmp(psi_key, LIBHAL_PROP_KEY, sizeof(LIBHAL_PROP_KEY)-1)){ + + /* only support strings for all values */ + tmp_val = get_prop_string(hal_ctx, udi, psi_key); + + if (tmp_val){ + add_option(&options, psi_key + sizeof(LIBHAL_PROP_KEY)-1, tmp_val); + xfree(tmp_val); + } + + /* evdev's XKB options... we should probably depreciate this usage */ + } else if (!strncasecmp(psi_key, LIBHAL_XKB_PROP_KEY, sizeof(LIBHAL_XKB_PROP_KEY)-1)){ + + /* only support strings for all values */ + tmp_val = get_prop_string(hal_ctx, udi, psi_key); + + if (tmp_val){ + /* add "xkb_" + NULL */ + tmp_key = xalloc(strlen(psi_key) - ( sizeof(LIBHAL_XKB_PROP_KEY) - 1) + 5); + + if (!tmp_key){ + LogMessage(X_ERROR, "config/hal: couldn't allocate memory for option %s\n", psi_key); + } else { + sprintf(tmp_key, "xkb_%s", psi_key + sizeof(LIBHAL_XKB_PROP_KEY)-1); + add_option(&options, tmp_key, tmp_val); + + xfree(tmp_key); + } + xfree(tmp_val); + } + } + } + + /* psi_key doesn't need to be freed */ + libhal_psi_next(&set_iter); + } + + /* this isn't an error, but how else do you output something that the user can see? */ + LogMessage(X_INFO, "config/hal: Adding input device %s\n", name); if (NewInputDeviceRequest(options, &dev) != Success) { - ErrorF("[config/hal] NewInputDeviceRequest failed\n"); + LogMessage(X_ERROR, "config/hal: NewInputDeviceRequest failed\n"); dev = NULL; goto unwind; } - for (; dev; dev = dev->next) + for (; dev; dev = dev->next){ + if (dev->config_info) + xfree(dev->config_info); dev->config_info = xstrdup(config_info); + } unwind: + if (set) + libhal_free_property_set(set); if (path) xfree(path); if (driver) xfree(driver); if (name) xfree(name); - if (xkb_rules) - xfree(xkb_rules); - if (xkb_model) - xfree(xkb_model); - if (xkb_layout) - xfree(xkb_layout); - if (xkb_variant) - xfree(xkb_variant); - if (xkb_options) - xfree(xkb_options); if (config_info) xfree(config_info); while (!dev && (tmpo = options)) { @@ -272,7 +306,6 @@ unwind: xfree(tmpo); } -out_error: dbus_error_free(&error); return; @@ -288,7 +321,7 @@ disconnect_hook(void *data) if (dbus_connection_get_is_connected(info->system_bus)) { dbus_error_init(&error); if (!libhal_ctx_shutdown(info->hal_ctx, &error)) - DebugF("[config/hal] couldn't shut down context: %s (%s)\n", + LogMessage(X_WARNING, "config/hal: disconnect_hook couldn't shut down context: %s (%s)\n", error.name, error.message); dbus_error_free(&error); } @@ -314,21 +347,21 @@ connect_hook(DBusConnection *connection, void *data) if (!info->hal_ctx) info->hal_ctx = libhal_ctx_new(); if (!info->hal_ctx) { - ErrorF("[config/hal] couldn't create HAL context\n"); + LogMessage(X_ERROR, "config/hal: couldn't create HAL context\n"); goto out_err; } if (!libhal_ctx_set_dbus_connection(info->hal_ctx, info->system_bus)) { - ErrorF("[config/hal] couldn't associate HAL context with bus\n"); + LogMessage(X_ERROR, "config/hal: couldn't associate HAL context with bus\n"); goto out_ctx; } if (!libhal_ctx_init(info->hal_ctx, &error)) { - ErrorF("[config/hal] couldn't initialise context: %s (%s)\n", + LogMessage(X_ERROR, "config/hal: couldn't initialise context: %s (%s)\n", error.name, error.message); goto out_ctx; } if (!libhal_device_property_watch_all(info->hal_ctx, &error)) { - ErrorF("[config/hal] couldn't watch all properties: %s (%s)\n", + LogMessage(X_ERROR, "config/hal: couldn't watch all properties: %s (%s)\n", error.name, error.message); goto out_ctx2; } @@ -348,7 +381,7 @@ connect_hook(DBusConnection *connection, void *data) out_ctx2: if (!libhal_ctx_shutdown(info->hal_ctx, &error)) - DebugF("[config/hal] couldn't shut down context: %s (%s)\n", + LogMessage(X_WARNING, "config/hal: couldn't shut down context: %s (%s)\n", error.name, error.message); out_ctx: libhal_ctx_free(info->hal_ctx); @@ -376,10 +409,13 @@ config_hal_init(void) hal_info.hal_ctx = NULL; if (!config_dbus_core_add_hook(&hook)) { - ErrorF("[config/hal] failed to add D-Bus hook\n"); + LogMessage(X_ERROR, "config/hal: failed to add D-Bus hook\n"); return 0; } + /* verbose message */ + LogMessageVerb(X_INFO,7,"config/hal: initialized"); + return 1; } diff --git a/config/x11-input.fdi b/config/x11-input.fdi index c390706fb..f2e2d50ab 100644 --- a/config/x11-input.fdi +++ b/config/x11-input.fdi @@ -1,7 +1,57 @@ - + + + mouse - base + base keyboard - pc105 + pc105 evdev - evdev + evdev - us + us - + diff --git a/configure.ac b/configure.ac index 3b2e7618c..b251dce7f 100644 --- a/configure.ac +++ b/configure.ac @@ -1025,6 +1025,8 @@ XKB_STUB_LIB='$(top_builddir)/xkb/libxkbstubs.la' AC_CHECK_FUNC(strcasecmp, [], AC_DEFINE([NEED_STRCASECMP], 1, [Do not have 'strcasecmp'.])) +AC_CHECK_FUNC(strncasecmp, [], AC_DEFINE([NEED_STRNCASECMP], 1, + [Do not have 'strncasecmp'.])) if test "x$NULL_ROOT_CURSOR" = xyes; then AC_DEFINE(NULL_ROOT_CURSOR, 1, [Use an empty root cursor]) From 82e7cf12453a4f91324c07581b59887dcc27014e Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 8 May 2008 14:05:56 +0930 Subject: [PATCH 07/12] config: remove trailing whitespaces. It makes my vim look ugly. Put "let c_space_errors=1" into your .vimrc. (cherry picked from commit 1f54c05cf8a6b82e5fc6362f7f8e8fdc2444b9e8) (cherry picked from commit 901978ebe0f446532255701cd536e246e805a55b) --- config/hal.c | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/config/hal.c b/config/hal.c index f9cffdb4e..07430489c 100644 --- a/config/hal.c +++ b/config/hal.c @@ -121,7 +121,7 @@ get_prop_string(LibHalContext *hal_ctx, const char *udi, const char *name) return ret; } -/* this function is no longer used... keep it here in case its needed in +/* this function is no longer used... keep it here in case its needed in * the future. */ #if 0 static char * @@ -157,7 +157,7 @@ get_prop_string_array(LibHalContext *hal_ctx, const char *udi, const char *prop) return ret; } -#endif +#endif static void device_added(LibHalContext *hal_ctx, const char *udi) @@ -166,12 +166,12 @@ device_added(LibHalContext *hal_ctx, const char *udi) InputOption *options = NULL, *tmpo = NULL; DeviceIntPtr dev; DBusError error; - + LibHalPropertySet *set = NULL; LibHalPropertySetIterator set_iter; char *psi_key = NULL, *tmp_val, *tmp_key; - - + + dbus_error_init(&error); driver = get_prop_string(hal_ctx, udi, "input.x11_driver"); @@ -180,13 +180,13 @@ device_added(LibHalContext *hal_ctx, const char *udi) LogMessageVerb(X_INFO,7,"config/hal: no driver specified for device %s\n", udi); goto unwind; } - + path = get_prop_string(hal_ctx, udi, "input.device"); if (!path) { LogMessage(X_WARNING,"config/hal: no driver or path specified for %s\n", udi); goto unwind; } - + name = get_prop_string(hal_ctx, udi, "info.product"); if (!name) name = xstrdup("(unnamed)"); @@ -196,7 +196,7 @@ device_added(LibHalContext *hal_ctx, const char *udi) LogMessage(X_ERROR, "config/hal: couldn't allocate space for input options!\n"); goto unwind; } - + options->key = xstrdup("_source"); options->value = xstrdup("server/hal"); if (!options->key || !options->value) { @@ -204,14 +204,14 @@ device_added(LibHalContext *hal_ctx, const char *udi) goto unwind; } - /* most drivers use device.. not path. evdev uses both however, but the + /* most drivers use device.. not path. evdev uses both however, but the * path version isn't documented apparently. support both for now. */ add_option(&options, "path", path); add_option(&options, "device", path); - + add_option(&options, "driver", driver); add_option(&options, "name", name); - + config_info = xalloc(strlen(udi) + 5); /* "hal:" and NULL */ if (!config_info) { LogMessage(X_ERROR, "config/hal: couldn't allocate name\n"); @@ -222,58 +222,58 @@ device_added(LibHalContext *hal_ctx, const char *udi) /* ok, grab options from hal.. iterate through all properties * and lets see if any of them are options that we can add */ set = libhal_device_get_all_properties(hal_ctx, udi, &error); - + if (!set) { LogMessage(X_ERROR, "config/hal: couldn't get property list for %s: %s (%s)\n", udi, error.name, error.message); goto unwind; } - + libhal_psi_init(&set_iter,set); while (libhal_psi_has_more(&set_iter)) { /* we are looking for supported keys.. extract and add to options */ - psi_key = libhal_psi_get_key(&set_iter); - + psi_key = libhal_psi_get_key(&set_iter); + if (psi_key){ /* normal options first (input.x11_options.) */ if (!strncasecmp(psi_key, LIBHAL_PROP_KEY, sizeof(LIBHAL_PROP_KEY)-1)){ - + /* only support strings for all values */ tmp_val = get_prop_string(hal_ctx, udi, psi_key); - + if (tmp_val){ add_option(&options, psi_key + sizeof(LIBHAL_PROP_KEY)-1, tmp_val); xfree(tmp_val); } - + /* evdev's XKB options... we should probably depreciate this usage */ } else if (!strncasecmp(psi_key, LIBHAL_XKB_PROP_KEY, sizeof(LIBHAL_XKB_PROP_KEY)-1)){ - + /* only support strings for all values */ tmp_val = get_prop_string(hal_ctx, udi, psi_key); - + if (tmp_val){ /* add "xkb_" + NULL */ tmp_key = xalloc(strlen(psi_key) - ( sizeof(LIBHAL_XKB_PROP_KEY) - 1) + 5); - + if (!tmp_key){ LogMessage(X_ERROR, "config/hal: couldn't allocate memory for option %s\n", psi_key); } else { sprintf(tmp_key, "xkb_%s", psi_key + sizeof(LIBHAL_XKB_PROP_KEY)-1); add_option(&options, tmp_key, tmp_val); - + xfree(tmp_key); } xfree(tmp_val); - } + } } } - + /* psi_key doesn't need to be freed */ libhal_psi_next(&set_iter); } - + /* this isn't an error, but how else do you output something that the user can see? */ LogMessage(X_INFO, "config/hal: Adding input device %s\n", name); if (NewInputDeviceRequest(options, &dev) != Success) { @@ -415,7 +415,7 @@ config_hal_init(void) /* verbose message */ LogMessageVerb(X_INFO,7,"config/hal: initialized"); - + return 1; } From 59a52d8151aeb607f39394ceb36ed69b9c2a15d5 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Thu, 8 May 2008 16:58:31 +0930 Subject: [PATCH 08/12] config: override xkb_{r,m,l,v} with Xkb{r,m,l,v} if the latter is set. The HAL spec says that input.xkb.{rmlv}* can be sent, but if the user specifies a X-specific {rmlv}, then this is overridden through the use of input.x11_options.Xkb{RMLV}. However, the way how the server parses options--by ignoring capitalisation, underscores and spaces--the HAL and the x11_options would override each other. So we simply filter the options, letting Xkb{RMLV} override xkb_{rmlv} and only actually add them to the device after parsing _all_ options. * rmlv ... rules, model, layout, variant See Bug 13037 (cherry picked from commit fc35d1e3be201e3821413bb2eeb8d43e1e56ba17) (cherry picked from commit ff013b0da4e6d33b2b69ce1212e9bd62050574e1) --- config/hal.c | 100 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 87 insertions(+), 13 deletions(-) diff --git a/config/hal.c b/config/hal.c index 07430489c..ac9e3d22a 100644 --- a/config/hal.c +++ b/config/hal.c @@ -48,6 +48,15 @@ struct config_hal_info { LibHalContext *hal_ctx; }; +/* Used for special handling of xkb options. */ +struct xkb_options { + char* layout; + char* model; + char* rules; + char* variant; +}; + + static void remove_device(DeviceIntPtr dev) { @@ -166,10 +175,11 @@ device_added(LibHalContext *hal_ctx, const char *udi) InputOption *options = NULL, *tmpo = NULL; DeviceIntPtr dev; DBusError error; + struct xkb_options xkb_opts = {0}; LibHalPropertySet *set = NULL; LibHalPropertySetIterator set_iter; - char *psi_key = NULL, *tmp_val, *tmp_key; + char *psi_key = NULL, *tmp_val; dbus_error_init(&error); @@ -243,27 +253,71 @@ device_added(LibHalContext *hal_ctx, const char *udi) tmp_val = get_prop_string(hal_ctx, udi, psi_key); if (tmp_val){ - add_option(&options, psi_key + sizeof(LIBHAL_PROP_KEY)-1, tmp_val); - xfree(tmp_val); - } + char* tmp; - /* evdev's XKB options... we should probably depreciate this usage */ + /* xkb needs special handling. HAL specs include + * input.xkb.xyz options, but the x11-input.fdi specifies + * input.x11_options.Xkbxyz options. By default, we use + * the former, unless the specific X11 ones are specified. + * Since we can't predict the order in which the keys + * arrive, we need to store them. + */ + if ((tmp = strcasestr(psi_key, "xkb"))) + { + if (!strcasecmp(&tmp[3], "layout")) + { + if (xkb_opts.layout) + xfree(xkb_opts.layout); + xkb_opts.layout = strdup(tmp_val); + } else if (!strcasecmp(&tmp[3], "model")) + { + if (xkb_opts.model) + xfree(xkb_opts.model); + xkb_opts.model = strdup(tmp_val); + } else if (!strcasecmp(&tmp[3], "rules")) + { + if (xkb_opts.rules) + xfree(xkb_opts.rules); + xkb_opts.rules = strdup(tmp_val); + } else if (!strcasecmp(&tmp[3], "variant")) + { + if (xkb_opts.variant) + xfree(xkb_opts.variant); + xkb_opts.variant = strdup(tmp_val); + } + } else + { + /* all others */ + add_option(&options, psi_key + sizeof(LIBHAL_PROP_KEY)-1, tmp_val); + xfree(tmp_val); + } + } } else if (!strncasecmp(psi_key, LIBHAL_XKB_PROP_KEY, sizeof(LIBHAL_XKB_PROP_KEY)-1)){ /* only support strings for all values */ tmp_val = get_prop_string(hal_ctx, udi, psi_key); if (tmp_val){ - /* add "xkb_" + NULL */ - tmp_key = xalloc(strlen(psi_key) - ( sizeof(LIBHAL_XKB_PROP_KEY) - 1) + 5); + char* tmp; - if (!tmp_key){ - LogMessage(X_ERROR, "config/hal: couldn't allocate memory for option %s\n", psi_key); - } else { - sprintf(tmp_key, "xkb_%s", psi_key + sizeof(LIBHAL_XKB_PROP_KEY)-1); - add_option(&options, tmp_key, tmp_val); + tmp = &psi_key[sizeof(LIBHAL_XKB_PROP_KEY) - 1]; - xfree(tmp_key); + if (!strcasecmp(tmp, "layout")) + { + if (!xkb_opts.layout) + xkb_opts.layout = strdup(tmp_val); + } else if (!strcasecmp(tmp, "rules")) + { + if (!xkb_opts.rules) + xkb_opts.rules = strdup(tmp_val); + } else if (!strcasecmp(tmp, "variant")) + { + if (!xkb_opts.variant) + xkb_opts.variant = strdup(tmp_val); + } else if (!strcasecmp(tmp, "model")) + { + if (!xkb_opts.model) + xkb_opts.model = strdup(tmp_val); } xfree(tmp_val); } @@ -274,6 +328,17 @@ device_added(LibHalContext *hal_ctx, const char *udi) libhal_psi_next(&set_iter); } + + /* Now add xkb options */ + if (xkb_opts.layout) + add_option(&options, "xkb_layout", xkb_opts.layout); + if (xkb_opts.rules) + add_option(&options, "xkb_rules", xkb_opts.rules); + if (xkb_opts.variant) + add_option(&options, "xkb_variant", xkb_opts.variant); + if (xkb_opts.model) + add_option(&options, "xkb_model", xkb_opts.model); + /* this isn't an error, but how else do you output something that the user can see? */ LogMessage(X_INFO, "config/hal: Adding input device %s\n", name); if (NewInputDeviceRequest(options, &dev) != Success) { @@ -306,6 +371,15 @@ unwind: xfree(tmpo); } + if (xkb_opts.layout) + xfree(xkb_opts.layout); + if (xkb_opts.rules) + xfree(xkb_opts.rules); + if (xkb_opts.model) + xfree(xkb_opts.model); + if (xkb_opts.variant) + xfree(xkb_opts.variant); + dbus_error_free(&error); return; From 38f573566e3218bd385a4940a6f9be700bc4f937 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 12 Jun 2008 09:04:24 +1000 Subject: [PATCH 09/12] dbe: fix DoS reported by iDefense. This isn't a security problem just a user could DoS themselves for fun or profit. (cherry picked from commit 23e71ef71a178505494d4b410f9314acfff81524) --- dbe/dbe.c | 53 +++++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/dbe/dbe.c b/dbe/dbe.c index 8175a352f..d34708d38 100644 --- a/dbe/dbe.c +++ b/dbe/dbe.c @@ -229,6 +229,7 @@ ProcDbeAllocateBackBufferName(ClientPtr client) xDbeSwapAction swapAction; VisualID visual; int status; + int add_index; REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq); @@ -299,14 +300,6 @@ ProcDbeAllocateBackBufferName(ClientPtr client) return(BadAlloc); bzero(pDbeWindowPriv, sizeof(DbeWindowPrivRec)); - /* Make the window priv a DBE window priv resource. */ - if (!AddResource(stuff->buffer, dbeWindowPrivResType, - (pointer)pDbeWindowPriv)) - { - xfree(pDbeWindowPriv); - return(BadAlloc); - } - /* Fill out window priv information. */ pDbeWindowPriv->pWindow = pWin; pDbeWindowPriv->width = pWin->drawable.width; @@ -321,14 +314,15 @@ ProcDbeAllocateBackBufferName(ClientPtr client) /* Initialize the buffer ID list. */ pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS; pDbeWindowPriv->IDs[0] = stuff->buffer; - for (i = 1; i < DBE_INIT_MAX_IDS; i++) + + add_index = 0; + for (i = 0; i < DBE_INIT_MAX_IDS; i++) { pDbeWindowPriv->IDs[i] = DBE_FREE_ID_ELEMENT; } - /* Actually connect the window priv to the window. */ - dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, pDbeWindowPriv); + dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, pDbeWindowPriv); } /* if -- There is no buffer associated with the window. */ @@ -354,7 +348,6 @@ ProcDbeAllocateBackBufferName(ClientPtr client) /* No more room in the ID array -- reallocate another array. */ XID *pIDs; - /* Setup an array pointer for the realloc operation below. */ if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS) { @@ -391,16 +384,7 @@ ProcDbeAllocateBackBufferName(ClientPtr client) pDbeWindowPriv->maxAvailableIDs += DBE_INCR_MAX_IDS; } - /* Finally, record the buffer ID in the array. */ - pDbeWindowPriv->IDs[i] = stuff->buffer; - - /* Associate the new ID with an existing window priv. */ - if (!AddResource(stuff->buffer, dbeWindowPrivResType, - (pointer)pDbeWindowPriv)) - { - pDbeWindowPriv->IDs[i] = DBE_FREE_ID_ELEMENT; - return(BadAlloc); - } + add_index = i; } /* else -- A buffer is already associated with the window. */ @@ -409,13 +393,26 @@ ProcDbeAllocateBackBufferName(ClientPtr client) status = (*pDbeScreenPriv->AllocBackBufferName)(pWin, stuff->buffer, stuff->swapAction); - if ((status != Success) && (pDbeWindowPriv->nBufferIDs == 0)) + if (status == Success) { + pDbeWindowPriv->IDs[add_index] = stuff->buffer; + if (!AddResource(stuff->buffer, dbeWindowPrivResType, + (pointer)pDbeWindowPriv)) + { + pDbeWindowPriv->IDs[add_index] = DBE_FREE_ID_ELEMENT; + + if (pDbeWindowPriv->nBufferIDs == 0) { + status = BadAlloc; + goto out_free; + } + } + } else { /* The DDX buffer allocation routine failed for the first buffer of * this window. */ - xfree(pDbeWindowPriv); - return(status); + if (pDbeWindowPriv->nBufferIDs == 0) { + goto out_free; + } } /* Increment the number of buffers (XIDs) associated with this window. */ @@ -424,9 +421,13 @@ ProcDbeAllocateBackBufferName(ClientPtr client) /* Set swap action on all calls. */ pDbeWindowPriv->swapAction = stuff->swapAction; - return(status); +out_free: + dixSetPrivate(&pWin->devPrivates, dbeWindowPrivKey, NULL); + xfree(pDbeWindowPriv); + return (status); + } /* ProcDbeAllocateBackBufferName() */ From 336a46c51932b9af7732e575f7ff43e41e47649e Mon Sep 17 00:00:00 2001 From: George Sapountzis Date: Fri, 23 May 2008 22:39:35 +0300 Subject: [PATCH 10/12] glx: fix memory corruption with r5g6b5 should cherry-pick to xserver-1.5 (cherry picked from commit 6c72961d8fa1ab1543f1b3e2cc7d34ff6d254bf8) --- GL/glx/glxscreens.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/GL/glx/glxscreens.c b/GL/glx/glxscreens.c index 5859de0b1..cc7054a64 100644 --- a/GL/glx/glxscreens.c +++ b/GL/glx/glxscreens.c @@ -420,10 +420,13 @@ findFirstSet(unsigned int v) static void initGlxVisual(VisualPtr visual, __GLXconfig *config) { + int maxBits; + maxBits = max(config->redBits, max(config->greenBits, config->blueBits)); + config->visualID = visual->vid; visual->class = glxConvertToXVisualType(config->visualType); - visual->bitsPerRGBValue = config->redBits; - visual->ColormapEntries = 1 << config->redBits; + visual->bitsPerRGBValue = maxBits; + visual->ColormapEntries = 1 << maxBits; visual->nplanes = config->redBits + config->greenBits + config->blueBits; visual->redMask = config->redMask; From 53a84d75c65f75c629c6610a2ec4093507cea3f7 Mon Sep 17 00:00:00 2001 From: Julien Cristau Date: Fri, 23 May 2008 23:00:40 +0200 Subject: [PATCH 11/12] xfree86: fix build on GNU/kFreeBSD GNU/kFreeBSD defines __FreeBSD_kernel__, but not __FreeBSD__. Unify preprocessor conditionals between variable declaration and use. Debian bug #482550. (cherry picked from commit e6cbb1e11e5da1a8b9001853c25f4e5a052e7110) --- hw/xfree86/os-support/bsd/bsd_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/xfree86/os-support/bsd/bsd_init.c b/hw/xfree86/os-support/bsd/bsd_init.c index 2c6a0256b..83583d5b9 100644 --- a/hw/xfree86/os-support/bsd/bsd_init.c +++ b/hw/xfree86/os-support/bsd/bsd_init.c @@ -159,7 +159,7 @@ xf86OpenConsole() xf86ConsOpen_t *driver; #if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) int result; -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) struct utsname uts; #endif vtmode_t vtmode; From 21248705bbd9876ea6d2d78a85bedc4904c63899 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 12 Jun 2008 14:54:56 +1000 Subject: [PATCH 12/12] modes: make aspect choosing work on single output case. In the single output enabled case we never enter the loop and test never gets set and so we fail to match a good mode. This was causing my 2560x1600 to end up at 2048x1536. --- hw/xfree86/modes/xf86Crtc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c index 855d646da..02c447d3a 100644 --- a/hw/xfree86/modes/xf86Crtc.c +++ b/hw/xfree86/modes/xf86Crtc.c @@ -1854,6 +1854,7 @@ bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect) nextEnabledOutput(config, enabled, &o); while ((mode = nextAspectMode(config->output[o], mode, aspect))) { + test = mode; for (p = o; nextEnabledOutput(config, enabled, &p); ) { test = xf86OutputFindClosestMode(config->output[p], mode); if (!test)