diff options
author | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2015-02-11 20:58:48 +0000 |
---|---|---|
committer | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2015-02-11 20:58:48 +0000 |
commit | 61c5fcfe608b38a9ce64b1db6393c392108cc89d (patch) | |
tree | 8ef036e5b54b6717be9c50782761a67170b6042d /xserver | |
parent | 4506119f5eb47a09843e68ff91de6ce5c63d0ba0 (diff) |
Update to xserver 1.16.4.
Contains fix for CVE-2015-0255. ok dcoppa@
Diffstat (limited to 'xserver')
-rw-r--r-- | xserver/ChangeLog | 190 | ||||
-rw-r--r-- | xserver/config/udev.c | 30 | ||||
-rw-r--r-- | xserver/configure | 20 | ||||
-rw-r--r-- | xserver/configure.ac | 2 | ||||
-rw-r--r-- | xserver/dix/dispatch.c | 2 | ||||
-rw-r--r-- | xserver/hw/xfree86/dri2/dri2.c | 3 | ||||
-rw-r--r-- | xserver/include/regionstr.h | 2 | ||||
-rw-r--r-- | xserver/os/WaitFor.c | 41 | ||||
-rw-r--r-- | xserver/randr/rroutput.c | 6 | ||||
-rw-r--r-- | xserver/randr/rrscreen.c | 22 | ||||
-rw-r--r-- | xserver/randr/rrxinerama.c | 12 | ||||
-rw-r--r-- | xserver/xkb/xkb.c | 100 |
12 files changed, 345 insertions, 85 deletions
diff --git a/xserver/ChangeLog b/xserver/ChangeLog index c830fb24c..d625f18f3 100644 --- a/xserver/ChangeLog +++ b/xserver/ChangeLog @@ -1,3 +1,193 @@ +commit ff76b219f6513b5ef63105165c301f7d69da0e05 +Author: Julien Cristau <jcristau@debian.org> +Date: Wed Feb 11 00:33:17 2015 +0100 + + Bump to 1.16.4 + + Signed-off-by: Julien Cristau <jcristau@debian.org> + +commit 8f61533b16635a0a13f4048235246edb138fa40b +Author: Olivier Fourdan <ofourdan@redhat.com> +Date: Fri Jan 16 08:44:45 2015 +0100 + + xkb: Check strings length against request size + + Ensure that the given strings length in an XkbSetGeometry request remain + within the limits of the size of the request. + + Signed-off-by: Olivier Fourdan <ofourdan@redhat.com> + Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net> + Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> + (cherry picked from commit 20079c36cf7d377938ca5478447d8b9045cb7d43) + (cherry picked from commit f160e722672dbb2b5215870b47bcc51461d96ff1) + Signed-off-by: Julien Cristau <jcristau@debian.org> + +commit 747cea16c4de1f48e838e1388301a2e24a3da6c4 +Author: Olivier Fourdan <ofourdan@redhat.com> +Date: Fri Jan 16 20:08:59 2015 +0100 + + xkb: Don't swap XkbSetGeometry data in the input buffer + + The XkbSetGeometry request embeds data which needs to be swapped when the + server and the client have different endianess. + + _XkbSetGeometry() invokes functions that swap these data directly in the + input buffer. + + However, ProcXkbSetGeometry() may call _XkbSetGeometry() more than once + (if there is more than one keyboard), thus causing on swapped clients the + same data to be swapped twice in memory, further causing a server crash + because the strings lengths on the second time are way off bounds. + + To allow _XkbSetGeometry() to run reliably more than once with swapped + clients, do not swap the data in the buffer, use variables instead. + + Signed-off-by: Olivier Fourdan <ofourdan@redhat.com> + Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> + (cherry picked from commit 81c90dc8f0aae3b65730409b1b615b5fa7280ebd) + (cherry picked from commit 29be310c303914090298ddda93a5bd5d00a94945) + Signed-off-by: Julien Cristau <jcristau@debian.org> + +commit 0722a8043c89e7224c398eef270611cc65c1e219 +Author: Chris Wilson <chris@chris-wilson.co.uk> +Date: Sat Jan 17 10:09:54 2015 +0000 + + dri2: SourceOffloads may be for DRI3 only + + As a DDX may declare offload support without supporting DRI2 + (because it is using an alternative acceleration mechanism like DRI3), + when iterating the list of offload_source Screens to find a matching + DRI2 provider we need to check before assuming it is DRI2 capable. + + Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=88514 + Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> + Reviewed-by: Dave Airlie <airlied@redhat.com> + Signed-off-by: Keith Packard <keithp@keithp.com> + (cherry picked from commit 082931014811e587a9734cbf4d88fd948979b641) + +commit f7e3478fe7817457017f31eb51803c4d03c69249 +Author: Adam Jackson <ajax@redhat.com> +Date: Mon Jan 5 16:48:11 2015 -0500 + + dix: make RegionInit legal C++ + + The CVE fix in: + + commit 97015a07b9e15d8ec5608b95d95ec0eb51202acb + Author: Alan Coopersmith <alan.coopersmith@oracle.com> + Date: Wed Jan 22 22:37:15 2014 -0800 + + dix: integer overflow in RegionSizeof() [CVE-2014-8092 3/4] + + offended the C++ demons: + + ../../include/regionstr.h:147:45: error: invalid conversion from 'void*' to + 'pixman_region16_data_t* {aka pixman_region16_data*}' [-fpermissive] + + Normally this isn't a problem, because around here we have the sense and + common decency to not use C++, but this does make tigervnc fail to build, + which is a little rude of us. + + Signed-off-by: Adam Jackson <ajax@redhat.com> + Reviewed-by: Alan Coopersmith <alan.coopersmith@oracle.com> + Signed-off-by: Keith Packard <keithp@keithp.com> + (cherry picked from commit bb23fbf5bb278113c9c481875423b4d128180972) + +commit 645ae07fac78dd2444fd744d3bf9b27e27d06e41 +Author: Dave Airlie <airlied@redhat.com> +Date: Fri Jan 30 09:59:49 2015 +1000 + + config/udev: Respect seat assignments when assigned devices + + Jonathan Dieter posted a few patches to do this inside the Xorg + server but it makes no sense to do it there, just have the code + we use to probe the device list at startup check seat assignments + using the same code we check at hotplug time. + + Bugilla: https://bugzilla.redhat.com/show_bug.cgi?id=1183654 + Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net> + Acked-by: Hans de Goede <hdegoede@redhat.com> + Tested-by: Jonathan Dieter <jdieter@lesbg.com> + Signed-off-by: Dave Airlie <airlied@redhat.com> + Signed-off-by: Keith Packard <keithp@keithp.com> + (cherry picked from commit 697b696e5e24d0679f133183a3bb0852025377c2) + +commit cdcf9e95108853e5ea2ed825a25e8f3b4d527535 +Author: Dave Airlie <airlied@redhat.com> +Date: Wed Jan 7 09:19:27 2015 +1000 + + randr: attempt to fix primary on slave output (v2) + + If the user wants to set one of the slave devices as + the primary output, we shouldn't fail to do so, + we were returning BadMatch which was tripping up + gnome-settings-daemon and bad things ensues. + + Fix all the places we use primaryOutput to work + out primaryCrtc and take it into a/c when slave + gpus are in use. + + v2: review from Aaron, fix indent, unhide has_primary from + macro. I left the int vs Bool alone to be consistent with + code below, a future patch could fix both. + + Signed-off-by: Dave Airlie <airlied@redhat.com> + Reviewed-by: Aaron Plattner <aplattner@nvidia.com> + Signed-off-by: Keith Packard <keithp@keithp.com> + (cherry picked from commit df1b401f57ad4b4925bad66684445b476562f26f) + +commit 5c4da5634505556c8249ba6da0adee9fb2621096 +Author: Nikhil Mahale <nmahale@nvidia.com> +Date: Sat Jan 24 17:06:59 2015 -0800 + + os: Fix timer race conditions + + Fixing following kind of race-conditions - + + WaitForSomething() + | + ----> // timers -> timer-1 -> timer-2 -> null + while (timers && (int) (timers->expires - now) <= 0) + // prototype - DoTimer(OsTimerPtr timer, CARD32 now, OsTimerPtr *prev) + DoTimer(timers, now, &timers) + | + | + ----> OsBlockSignals(); .... OS Signal comes just before blocking it, + .... timer-1 handler gets called. + // timer-1 gets served and scheduled again; + // timers -> timer-2 -> timer-1 -> null + .... + *prev = timer->next; + timer->next = NULL; // timers -> null + // timers list gets corrupted here and timer-2 gets removed from list. + + Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=86288 + Signed-off-by: Nikhil Mahale <nmahale@nvidia.com> + Reviewed-by: Julien Cristau <jcristau@debian.org> + + v2: Apply warning fixes from Keith Packard <keithp@keithp.com> + + Reviewed-by: Aaron Plattner <aplattner@nvidia.com> + Signed-off-by: Aaron Plattner <aplattner@nvidia.com> + Signed-off-by: Keith Packard <keithp@keithp.com> + (cherry picked from commit fe4c774c572e3f55a7417f0ca336ae1479a966ad) + +commit f39ac527baab8a38d023e3a8416757ccfcead42a +Author: Keith Packard <keithp@keithp.com> +Date: Sat Jan 3 08:46:45 2015 -0800 + + dix: Allow zero-height PutImage requests + + The length checking code validates PutImage height and byte width by + making sure that byte-width >= INT32_MAX / height. If height is zero, + this generates a divide by zero exception. Allow zero height requests + explicitly, bypassing the INT32_MAX check. + + Signed-off-by: Keith Packard <keithp@keithp.com> + Reviewed-by: Alan Coopersmith <alan.coopersmith@oracle.com> + (cherry picked from commit dc777c346d5d452a53b13b917c45f6a1bad2f20b) + Signed-off-by: Julien Cristau <jcristau@debian.org> + commit 16f157cbf6b9c3193b4e622b9c4552e83a343e9d Author: Julien Cristau <jcristau@debian.org> Date: Sat Dec 20 12:38:41 2014 +0100 diff --git a/xserver/config/udev.c b/xserver/config/udev.c index a1b72c13b..71215afb3 100644 --- a/xserver/config/udev.c +++ b/xserver/config/udev.c @@ -69,6 +69,24 @@ static const char *itoa(int i) return itoa_buf; } +static Bool +check_seat(struct udev_device *udev_device) +{ + const char *dev_seat; + + dev_seat = udev_device_get_property_value(udev_device, "ID_SEAT"); + if (!dev_seat) + dev_seat = "seat0"; + + if (SeatId && strcmp(dev_seat, SeatId)) + return FALSE; + + if (!SeatId && strcmp(dev_seat, "seat0")) + return FALSE; + + return TRUE; +} + static void device_added(struct udev_device *udev_device) { @@ -83,7 +101,6 @@ device_added(struct udev_device *udev_device) struct udev_list_entry *set, *entry; struct udev_device *parent; int rc; - const char *dev_seat; dev_t devnum; path = udev_device_get_devnode(udev_device); @@ -93,14 +110,7 @@ device_added(struct udev_device *udev_device) if (!path || !syspath) return; - dev_seat = udev_device_get_property_value(udev_device, "ID_SEAT"); - if (!dev_seat) - dev_seat = "seat0"; - - if (SeatId && strcmp(dev_seat, SeatId)) - return; - - if (!SeatId && strcmp(dev_seat, "seat0")) + if (!check_seat(udev_device)) return; devnum = udev_device_get_devnum(udev_device); @@ -506,6 +516,8 @@ config_udev_odev_probe(config_odev_probe_proc_ptr probe_callback) goto no_probe; else if (strncmp(sysname, "card", 4) != 0) goto no_probe; + else if (!check_seat(udev_device)) + goto no_probe; config_udev_odev_setup_attribs(path, syspath, major(devnum), minor(devnum), probe_callback); diff --git a/xserver/configure b/xserver/configure index a56fcab97..1e3cb89b1 100644 --- a/xserver/configure +++ b/xserver/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for xorg-server 1.16.3. +# Generated by GNU Autoconf 2.69 for xorg-server 1.16.4. # # Report bugs to <https://bugs.freedesktop.org/enter_bug.cgi?product=xorg>. # @@ -651,8 +651,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='xorg-server' PACKAGE_TARNAME='xorg-server' -PACKAGE_VERSION='1.16.3' -PACKAGE_STRING='xorg-server 1.16.3' +PACKAGE_VERSION='1.16.4' +PACKAGE_STRING='xorg-server 1.16.4' PACKAGE_BUGREPORT='https://bugs.freedesktop.org/enter_bug.cgi?product=xorg' PACKAGE_URL='' @@ -2063,7 +2063,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures xorg-server 1.16.3 to adapt to many kinds of systems. +\`configure' configures xorg-server 1.16.4 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -2133,7 +2133,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of xorg-server 1.16.3:";; + short | recursive ) echo "Configuration of xorg-server 1.16.4:";; esac cat <<\_ACEOF @@ -2579,7 +2579,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -xorg-server configure 1.16.3 +xorg-server configure 1.16.4 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -3288,7 +3288,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by xorg-server $as_me 1.16.3, which was +It was created by xorg-server $as_me 1.16.4, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -4116,7 +4116,7 @@ fi # Define the identity of the package. PACKAGE='xorg-server' - VERSION='1.16.3' + VERSION='1.16.4' cat >>confdefs.h <<_ACEOF @@ -32693,7 +32693,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by xorg-server $as_me 1.16.3, which was +This file was extended by xorg-server $as_me 1.16.4, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -32759,7 +32759,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -xorg-server config.status 1.16.3 +xorg-server config.status 1.16.4 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/xserver/configure.ac b/xserver/configure.ac index 1ad1f92ba..894eb506b 100644 --- a/xserver/configure.ac +++ b/xserver/configure.ac @@ -26,7 +26,7 @@ dnl dnl Process this file with autoconf to create configure. AC_PREREQ(2.60) -AC_INIT([xorg-server], 1.16.3, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server) +AC_INIT([xorg-server], 1.16.4, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server) RELEASE_DATE="2014-12-20" RELEASE_NAME="Marionberry Pie" AC_CONFIG_SRCDIR([Makefile.am]) diff --git a/xserver/dix/dispatch.c b/xserver/dix/dispatch.c index 01820bc0f..4e24e627f 100644 --- a/xserver/dix/dispatch.c +++ b/xserver/dix/dispatch.c @@ -1956,7 +1956,7 @@ ProcPutImage(ClientPtr client) tmpImage = (char *) &stuff[1]; lengthProto = length; - if (lengthProto >= (INT32_MAX / stuff->height)) + if (stuff->height != 0 && lengthProto >= (INT32_MAX / stuff->height)) return BadLength; if ((bytes_to_int32(lengthProto * stuff->height) + diff --git a/xserver/hw/xfree86/dri2/dri2.c b/xserver/hw/xfree86/dri2/dri2.c index 6459f11b1..f64ba7ca9 100644 --- a/xserver/hw/xfree86/dri2/dri2.c +++ b/xserver/hw/xfree86/dri2/dri2.c @@ -156,6 +156,9 @@ GetScreenPrime(ScreenPtr master, int prime_id) DRI2ScreenPtr ds; ds = DRI2GetScreen(slave); + if (ds == NULL) + continue; + if (ds->prime_id == prime_id) return slave; } diff --git a/xserver/include/regionstr.h b/xserver/include/regionstr.h index 33df87f0a..00343f27f 100644 --- a/xserver/include/regionstr.h +++ b/xserver/include/regionstr.h @@ -144,7 +144,7 @@ RegionInit(RegionPtr _pReg, BoxPtr _rect, int _size) size_t rgnSize; (_pReg)->extents = RegionEmptyBox; if (((_size) > 1) && ((rgnSize = RegionSizeof(_size)) > 0) && - (((_pReg)->data = malloc(rgnSize)) != NULL)) { + (((_pReg)->data = (RegDataPtr) malloc(rgnSize)) != NULL)) { (_pReg)->data->size = (_size); (_pReg)->data->numRects = 0; } diff --git a/xserver/os/WaitFor.c b/xserver/os/WaitFor.c index 3eb15b9b8..343de0c50 100644 --- a/xserver/os/WaitFor.c +++ b/xserver/os/WaitFor.c @@ -121,9 +121,9 @@ struct _OsTimerRec { void *arg; }; -static void DoTimer(OsTimerPtr timer, CARD32 now, OsTimerPtr *prev); +static void DoTimer(OsTimerPtr timer, CARD32 now, volatile OsTimerPtr *prev); static void CheckAllTimers(void); -static OsTimerPtr timers = NULL; +static volatile OsTimerPtr timers = NULL; /***************** * WaitForSomething: @@ -263,11 +263,14 @@ WaitForSomething(int *pClientsReady) if ((int) (timers->expires - now) <= 0) expired = 1; - while (timers && (int) (timers->expires - now) <= 0) - DoTimer(timers, now, &timers); + if (expired) { + OsBlockSignals(); + while (timers && (int) (timers->expires - now) <= 0) + DoTimer(timers, now, &timers); + OsReleaseSignals(); - if (expired) return 0; + } } } else { @@ -281,11 +284,14 @@ WaitForSomething(int *pClientsReady) if ((int) (timers->expires - now) <= 0) expired = 1; - while (timers && (int) (timers->expires - now) <= 0) - DoTimer(timers, now, &timers); + if (expired) { + OsBlockSignals(); + while (timers && (int) (timers->expires - now) <= 0) + DoTimer(timers, now, &timers); + OsReleaseSignals(); - if (expired) return 0; + } } } if (someReady) @@ -401,24 +407,25 @@ CheckAllTimers(void) } static void -DoTimer(OsTimerPtr timer, CARD32 now, OsTimerPtr *prev) +DoTimer(OsTimerPtr timer, CARD32 now, volatile OsTimerPtr *prev) { CARD32 newTime; OsBlockSignals(); *prev = timer->next; timer->next = NULL; + OsReleaseSignals(); + newTime = (*timer->callback) (timer, now, timer->arg); if (newTime) TimerSet(timer, 0, newTime, timer->callback, timer->arg); - OsReleaseSignals(); } OsTimerPtr TimerSet(OsTimerPtr timer, int flags, CARD32 millis, OsTimerCallback func, void *arg) { - register OsTimerPtr *prev; + volatile OsTimerPtr *prev; CARD32 now = GetTimeInMillis(); if (!timer) { @@ -470,7 +477,7 @@ Bool TimerForce(OsTimerPtr timer) { int rc = FALSE; - OsTimerPtr *prev; + volatile OsTimerPtr *prev; OsBlockSignals(); for (prev = &timers; *prev; prev = &(*prev)->next) { @@ -487,7 +494,7 @@ TimerForce(OsTimerPtr timer) void TimerCancel(OsTimerPtr timer) { - OsTimerPtr *prev; + volatile OsTimerPtr *prev; if (!timer) return; @@ -515,8 +522,12 @@ TimerCheck(void) { CARD32 now = GetTimeInMillis(); - while (timers && (int) (timers->expires - now) <= 0) - DoTimer(timers, now, &timers); + if (timers && (int) (timers->expires - now) <= 0) { + OsBlockSignals(); + while (timers && (int) (timers->expires - now) <= 0) + DoTimer(timers, now, &timers); + OsReleaseSignals(); + } } void diff --git a/xserver/randr/rroutput.c b/xserver/randr/rroutput.c index f824f50ed..1649309dc 100644 --- a/xserver/randr/rroutput.c +++ b/xserver/randr/rroutput.c @@ -540,7 +540,11 @@ ProcRRSetOutputPrimary(ClientPtr client) if (stuff->output) { VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess); - if (output->pScreen != pWin->drawable.pScreen) { + if (!output->pScreen->isGPU && output->pScreen != pWin->drawable.pScreen) { + client->errorValue = stuff->window; + return BadMatch; + } + if (output->pScreen->isGPU && output->pScreen->current_master != pWin->drawable.pScreen) { client->errorValue = stuff->window; return BadMatch; } diff --git a/xserver/randr/rrscreen.c b/xserver/randr/rrscreen.c index 36179ae89..e7ea49ddf 100644 --- a/xserver/randr/rrscreen.c +++ b/xserver/randr/rrscreen.c @@ -322,8 +322,13 @@ static inline void swap_modeinfos(xRRModeInfo *modeinfos, int i) swapl(&modeinfos[i].modeFlags); } -#define update_arrays(gpuscreen, pScrPriv) do { \ +#define update_arrays(gpuscreen, pScrPriv, primary_crtc, has_primary) do { \ for (j = 0; j < pScrPriv->numCrtcs; j++) { \ + if (has_primary && \ + primary_crtc == pScrPriv->crtcs[j]) { \ + has_primary = 0; \ + continue; \ + }\ crtcs[crtc_count] = pScrPriv->crtcs[j]->id; \ if (client->swapped) \ swapl(&crtcs[crtc_count]); \ @@ -366,9 +371,11 @@ rrGetMultiScreenResources(ClientPtr client, Bool query, ScreenPtr pScreen) unsigned long extraLen; CARD8 *extra; RRCrtc *crtcs; + RRCrtcPtr primary_crtc = NULL; RROutput *outputs; xRRModeInfo *modeinfos; CARD8 *names; + int has_primary = 0; /* we need to iterate all the GPU masters and all their output slaves */ total_crtcs = 0; @@ -426,18 +433,25 @@ rrGetMultiScreenResources(ClientPtr client, Bool query, ScreenPtr pScreen) modeinfos = (xRRModeInfo *)(outputs + total_outputs); names = (CARD8 *)(modeinfos + total_modes); - /* TODO primary */ crtc_count = 0; output_count = 0; mode_count = 0; pScrPriv = rrGetScrPriv(pScreen); - update_arrays(pScreen, pScrPriv); + if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc) { + has_primary = 1; + primary_crtc = pScrPriv->primaryOutput->crtc; + crtcs[0] = pScrPriv->primaryOutput->crtc->id; + if (client->swapped) + swapl(&crtcs[0]); + crtc_count = 1; + } + update_arrays(pScreen, pScrPriv, primary_crtc, has_primary); xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) { pScrPriv = rrGetScrPriv(iter); - update_arrays(iter, pScrPriv); + update_arrays(iter, pScrPriv, primary_crtc, has_primary); } assert(bytes_to_int32((char *) names - (char *) extra) == rep.length); diff --git a/xserver/randr/rrxinerama.c b/xserver/randr/rrxinerama.c index 76d728c70..363ceadd2 100644 --- a/xserver/randr/rrxinerama.c +++ b/xserver/randr/rrxinerama.c @@ -344,15 +344,17 @@ ProcRRXineramaQueryScreens(ClientPtr client) ScreenPtr slave; rrScrPriv(pScreen); int has_primary = 0; + RRCrtcPtr primary_crtc = NULL; if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc) { has_primary = 1; + primary_crtc = pScrPriv->primaryOutput->crtc; RRXineramaWriteCrtc(client, pScrPriv->primaryOutput->crtc); } for (i = 0; i < pScrPriv->numCrtcs; i++) { if (has_primary && - pScrPriv->primaryOutput->crtc == pScrPriv->crtcs[i]) { + primary_crtc == pScrPriv->crtcs[i]) { has_primary = 0; continue; } @@ -362,8 +364,14 @@ ProcRRXineramaQueryScreens(ClientPtr client) xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) { rrScrPrivPtr pSlavePriv; pSlavePriv = rrGetScrPriv(slave); - for (i = 0; i < pSlavePriv->numCrtcs; i++) + for (i = 0; i < pSlavePriv->numCrtcs; i++) { + if (has_primary && + primary_crtc == pSlavePriv->crtcs[i]) { + has_primary = 0; + continue; + } RRXineramaWriteCrtc(client, pSlavePriv->crtcs[i]); + } } } diff --git a/xserver/xkb/xkb.c b/xserver/xkb/xkb.c index dc570f0e5..c8a9e9e3f 100644 --- a/xserver/xkb/xkb.c +++ b/xserver/xkb/xkb.c @@ -4957,26 +4957,29 @@ ProcXkbGetGeometry(ClientPtr client) /***====================================================================***/ -static char * -_GetCountedString(char **wire_inout, Bool swap) +static Status +_GetCountedString(char **wire_inout, ClientPtr client, char **str) { - char *wire, *str; - CARD16 len, *plen; + char *wire, *next; + CARD16 len; wire = *wire_inout; - plen = (CARD16 *) wire; - if (swap) { - swaps(plen); - } - len = *plen; - str = malloc(len + 1); - if (str) { - memcpy(str, &wire[2], len); - str[len] = '\0'; + len = *(CARD16 *) wire; + if (client->swapped) { + swaps(&len); } - wire += XkbPaddedSize(len + 2); - *wire_inout = wire; - return str; + next = wire + XkbPaddedSize(len + 2); + /* Check we're still within the size of the request */ + if (client->req_len < + bytes_to_int32(next - (char *) client->requestBuffer)) + return BadValue; + *str = malloc(len + 1); + if (!*str) + return BadAlloc; + memcpy(*str, &wire[2], len); + *(*str + len) = '\0'; + *wire_inout = next; + return Success; } static Status @@ -4985,25 +4988,29 @@ _CheckSetDoodad(char **wire_inout, { char *wire; xkbDoodadWireDesc *dWire; + xkbAnyDoodadWireDesc any; + xkbTextDoodadWireDesc text; XkbDoodadPtr doodad; + Status status; dWire = (xkbDoodadWireDesc *) (*wire_inout); + any = dWire->any; wire = (char *) &dWire[1]; if (client->swapped) { - swapl(&dWire->any.name); - swaps(&dWire->any.top); - swaps(&dWire->any.left); - swaps(&dWire->any.angle); + swapl(&any.name); + swaps(&any.top); + swaps(&any.left); + swaps(&any.angle); } CHK_ATOM_ONLY(dWire->any.name); - doodad = XkbAddGeomDoodad(geom, section, dWire->any.name); + doodad = XkbAddGeomDoodad(geom, section, any.name); if (!doodad) return BadAlloc; doodad->any.type = dWire->any.type; doodad->any.priority = dWire->any.priority; - doodad->any.top = dWire->any.top; - doodad->any.left = dWire->any.left; - doodad->any.angle = dWire->any.angle; + doodad->any.top = any.top; + doodad->any.left = any.left; + doodad->any.angle = any.angle; switch (doodad->any.type) { case XkbOutlineDoodad: case XkbSolidDoodad: @@ -5026,15 +5033,22 @@ _CheckSetDoodad(char **wire_inout, dWire->text.colorNdx); return BadMatch; } + text = dWire->text; if (client->swapped) { - swaps(&dWire->text.width); - swaps(&dWire->text.height); + swaps(&text.width); + swaps(&text.height); } - doodad->text.width = dWire->text.width; - doodad->text.height = dWire->text.height; + doodad->text.width = text.width; + doodad->text.height = text.height; doodad->text.color_ndx = dWire->text.colorNdx; - doodad->text.text = _GetCountedString(&wire, client->swapped); - doodad->text.font = _GetCountedString(&wire, client->swapped); + status = _GetCountedString(&wire, client, &doodad->text.text); + if (status != Success) + return status; + status = _GetCountedString(&wire, client, &doodad->text.font); + if (status != Success) { + free (doodad->text.text); + return status; + } break; case XkbIndicatorDoodad: if (dWire->indicator.onColorNdx >= geom->num_colors) { @@ -5069,7 +5083,9 @@ _CheckSetDoodad(char **wire_inout, } doodad->logo.color_ndx = dWire->logo.colorNdx; doodad->logo.shape_ndx = dWire->logo.shapeNdx; - doodad->logo.logo_name = _GetCountedString(&wire, client->swapped); + status = _GetCountedString(&wire, client, &doodad->logo.logo_name); + if (status != Success) + return status; break; default: client->errorValue = _XkbErrCode2(0x4F, dWire->any.type); @@ -5301,18 +5317,20 @@ _CheckSetGeom(XkbGeometryPtr geom, xkbSetGeometryReq * req, ClientPtr client) char *wire; wire = (char *) &req[1]; - geom->label_font = _GetCountedString(&wire, client->swapped); + status = _GetCountedString(&wire, client, &geom->label_font); + if (status != Success) + return status; for (i = 0; i < req->nProperties; i++) { char *name, *val; - name = _GetCountedString(&wire, client->swapped); - if (!name) - return BadAlloc; - val = _GetCountedString(&wire, client->swapped); - if (!val) { + status = _GetCountedString(&wire, client, &name); + if (status != Success) + return status; + status = _GetCountedString(&wire, client, &val); + if (status != Success) { free(name); - return BadAlloc; + return status; } if (XkbAddGeomProperty(geom, name, val) == NULL) { free(name); @@ -5346,9 +5364,9 @@ _CheckSetGeom(XkbGeometryPtr geom, xkbSetGeometryReq * req, ClientPtr client) for (i = 0; i < req->nColors; i++) { char *name; - name = _GetCountedString(&wire, client->swapped); - if (!name) - return BadAlloc; + status = _GetCountedString(&wire, client, &name); + if (status != Success) + return status; if (!XkbAddGeomColor(geom, name, geom->num_colors)) { free(name); return BadAlloc; |