summaryrefslogtreecommitdiff
path: root/xserver
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2015-02-11 20:58:48 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2015-02-11 20:58:48 +0000
commit61c5fcfe608b38a9ce64b1db6393c392108cc89d (patch)
tree8ef036e5b54b6717be9c50782761a67170b6042d /xserver
parent4506119f5eb47a09843e68ff91de6ce5c63d0ba0 (diff)
Update to xserver 1.16.4.
Contains fix for CVE-2015-0255. ok dcoppa@
Diffstat (limited to 'xserver')
-rw-r--r--xserver/ChangeLog190
-rw-r--r--xserver/config/udev.c30
-rw-r--r--xserver/configure20
-rw-r--r--xserver/configure.ac2
-rw-r--r--xserver/dix/dispatch.c2
-rw-r--r--xserver/hw/xfree86/dri2/dri2.c3
-rw-r--r--xserver/include/regionstr.h2
-rw-r--r--xserver/os/WaitFor.c41
-rw-r--r--xserver/randr/rroutput.c6
-rw-r--r--xserver/randr/rrscreen.c22
-rw-r--r--xserver/randr/rrxinerama.c12
-rw-r--r--xserver/xkb/xkb.c100
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;