From 7e1c3b94f42dfc5e52f0f724b6bf7d03e3b743e3 Mon Sep 17 00:00:00 2001 From: Mike DePaulo Date: Sat, 10 Jan 2015 12:03:47 -0500 Subject: Fix CVE-2014-8091..8103. Patches were ported from Ubuntu 14.04 (xorg-server 1.15.1) --- xorg-server/test/misc.c | 37 +++++++ xorg-server/test/xi1/Makefile.am | 34 ++++++ .../test/xi1/protocol-xchangedevicecontrol.c | 122 +++++++++++++++++++++ xorg-server/test/xi2/protocol-xigetclientpointer.c | 5 + .../test/xi2/protocol-xipassivegrabdevice.c | 8 ++ xorg-server/test/xi2/protocol-xiquerypointer.c | 4 + xorg-server/test/xi2/protocol-xiwarppointer.c | 3 + 7 files changed, 213 insertions(+) create mode 100644 xorg-server/test/xi1/Makefile.am create mode 100644 xorg-server/test/xi1/protocol-xchangedevicecontrol.c (limited to 'xorg-server/test') diff --git a/xorg-server/test/misc.c b/xorg-server/test/misc.c index dd792e692..66330a140 100644 --- a/xorg-server/test/misc.c +++ b/xorg-server/test/misc.c @@ -28,6 +28,8 @@ #include #include "misc.h" #include "scrnintstr.h" +#include "dix.h" +#include "dixstruct.h" ScreenInfo screenInfo; @@ -155,11 +157,46 @@ dix_update_desktop_dimensions(void) assert_dimensions(-w2, -h2, w2, h2); } +static int +dix_request_fixed_size_overflow(ClientRec *client) +{ + xReq req = { 0 }; + + client->req_len = req.length = 1; + REQUEST_FIXED_SIZE(req, SIZE_MAX); + return Success; +} + +static int +dix_request_fixed_size_match(ClientRec *client) +{ + xReq req = { 0 }; + + client->req_len = req.length = 9; + REQUEST_FIXED_SIZE(req, 30); + return Success; +} + +static void +dix_request_size_checks(void) +{ + ClientRec client = { 0 }; + int rc; + + rc = dix_request_fixed_size_overflow(&client); + assert(rc == BadLength); + + rc = dix_request_fixed_size_match(&client); + assert(rc == Success); +} + + int main(int argc, char **argv) { dix_version_compare(); dix_update_desktop_dimensions(); + dix_request_size_checks(); return 0; } diff --git a/xorg-server/test/xi1/Makefile.am b/xorg-server/test/xi1/Makefile.am new file mode 100644 index 000000000..907fa7aea --- /dev/null +++ b/xorg-server/test/xi1/Makefile.am @@ -0,0 +1,34 @@ +if ENABLE_UNIT_TESTS +if HAVE_LD_WRAP +noinst_PROGRAMS = \ + protocol-xchangedevicecontrol + +TESTS=$(noinst_PROGRAMS) +TESTS_ENVIRONMENT = $(XORG_MALLOC_DEBUG_ENV) + +AM_CFLAGS = $(DIX_CFLAGS) @XORG_CFLAGS@ +AM_CPPFLAGS = @XORG_INCS@ -I$(srcdir)/../xi2 +TEST_LDADD=../libxservertest.la $(XORG_SYS_LIBS) $(XSERVER_SYS_LIBS) $(GLX_SYS_LIBS) +COMMON_SOURCES=$(srcdir)/../xi2/protocol-common.c + +if SPECIAL_DTRACE_OBJECTS +TEST_LDADD += $(OS_LIB) $(DIX_LIB) +endif + +protocol_xchangedevicecontrol_LDADD=$(TEST_LDADD) + +protocol_xchangedevicecontrol_LDFLAGS=$(AM_LDFLAGS) -Wl,-wrap,WriteToClient + +protocol_xchangedevicecontrol_SOURCES=$(COMMON_SOURCES) protocol-xchangedevicecontrol.c + +else +# Print that xi1-tests were skipped (exit code 77 for automake test harness) +TESTS = xi1-tests +CLEANFILES = $(TESTS) + +xi1-tests: + @echo 'echo "ld -wrap support required for xi1 unit tests, skipping"' > $@ + @echo 'exit 77' >> $@ + $(AM_V_GEN)chmod +x $@ +endif +endif diff --git a/xorg-server/test/xi1/protocol-xchangedevicecontrol.c b/xorg-server/test/xi1/protocol-xchangedevicecontrol.c new file mode 100644 index 000000000..8e638b218 --- /dev/null +++ b/xorg-server/test/xi1/protocol-xchangedevicecontrol.c @@ -0,0 +1,122 @@ +/** + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +/* + * Protocol testing for ChangeDeviceControl request. + */ +#include +#include +#include +#include +#include "inputstr.h" +#include "chgdctl.h" + +#include "protocol-common.h" + +static ClientRec client_request; + +static void +reply_ChangeDeviceControl(ClientPtr client, int len, char *data, void *userdata) +{ + xChangeDeviceControlReply *rep = (xChangeDeviceControlReply *) data; + + if (client->swapped) { + swapl(&rep->length); + swaps(&rep->sequenceNumber); + } + + reply_check_defaults(rep, len, ChangeDeviceControl); + + /* XXX: check status code in reply */ +} + +static void +request_ChangeDeviceControl(ClientPtr client, xChangeDeviceControlReq * req, + xDeviceCtl *ctl, int error) +{ + int rc; + + client_request.req_len = req->length; + rc = ProcXChangeDeviceControl(&client_request); + assert(rc == error); + + /* XXX: ChangeDeviceControl doesn't seem to fill in errorValue to check */ + + client_request.swapped = TRUE; + swaps(&req->length); + swaps(&req->control); + swaps(&ctl->length); + swaps(&ctl->control); + /* XXX: swap other contents of ctl, depending on type */ + rc = SProcXChangeDeviceControl(&client_request); + assert(rc == error); +} + +static unsigned char *data[4096]; /* the request buffer */ + +static void +test_ChangeDeviceControl(void) +{ + xChangeDeviceControlReq *request = (xChangeDeviceControlReq *) data; + xDeviceCtl *control = (xDeviceCtl *) (&request[1]); + + request_init(request, ChangeDeviceControl); + + reply_handler = reply_ChangeDeviceControl; + + client_request = init_client(request->length, request); + + printf("Testing invalid lengths:\n"); + printf(" -- no control struct\n"); + request_ChangeDeviceControl(&client_request, request, control, BadLength); + + printf(" -- xDeviceResolutionCtl\n"); + request_init(request, ChangeDeviceControl); + request->control = DEVICE_RESOLUTION; + control->length = (sizeof(xDeviceResolutionCtl) >> 2); + request->length += control->length - 2; + request_ChangeDeviceControl(&client_request, request, control, BadLength); + + printf(" -- xDeviceEnableCtl\n"); + request_init(request, ChangeDeviceControl); + request->control = DEVICE_ENABLE; + control->length = (sizeof(xDeviceEnableCtl) >> 2); + request->length += control->length - 2; + request_ChangeDeviceControl(&client_request, request, control, BadLength); + + /* XXX: Test functionality! */ +} + +int +main(int argc, char **argv) +{ + init_simple(); + + test_ChangeDeviceControl(); + + return 0; +} diff --git a/xorg-server/test/xi2/protocol-xigetclientpointer.c b/xorg-server/test/xi2/protocol-xigetclientpointer.c index 28eb8d32a..570c53e06 100644 --- a/xorg-server/test/xi2/protocol-xigetclientpointer.c +++ b/xorg-server/test/xi2/protocol-xigetclientpointer.c @@ -124,6 +124,11 @@ test_XIGetClientPointer(void) request.win = INVALID_WINDOW_ID; request_XIGetClientPointer(&client_request, &request, BadWindow); + printf("Testing invalid length\n"); + client_request.req_len -= 4; + request_XIGetClientPointer(&client_request, &request, BadLength); + client_request.req_len += 4; + test_data.cp_is_set = FALSE; printf("Testing window None, unset ClientPointer.\n"); diff --git a/xorg-server/test/xi2/protocol-xipassivegrabdevice.c b/xorg-server/test/xi2/protocol-xipassivegrabdevice.c index c747ddf03..95d8ebf2b 100644 --- a/xorg-server/test/xi2/protocol-xipassivegrabdevice.c +++ b/xorg-server/test/xi2/protocol-xipassivegrabdevice.c @@ -139,6 +139,7 @@ request_XIPassiveGrabDevice(ClientPtr client, xXIPassiveGrabDeviceReq * req, int local_modifiers; int mask_len; + client_request.req_len = req->length; rc = ProcXIPassiveGrabDevice(&client_request); assert(rc == error); @@ -190,6 +191,13 @@ test_XIPassiveGrabDevice(void) request_XIPassiveGrabDevice(&client_request, request, BadDevice, request->deviceid); + printf("Testing invalid length\n"); + request->length -= 2; + request_XIPassiveGrabDevice(&client_request, request, BadLength, + client_request.errorValue); + /* re-init request since swapped length test leaves some values swapped */ + request_init(request, XIPassiveGrabDevice); + request->grab_window = CLIENT_WINDOW_ID; request->deviceid = XIAllMasterDevices; printf("Testing invalid grab types\n"); diff --git a/xorg-server/test/xi2/protocol-xiquerypointer.c b/xorg-server/test/xi2/protocol-xiquerypointer.c index fc66b6429..c0421f6dd 100644 --- a/xorg-server/test/xi2/protocol-xiquerypointer.c +++ b/xorg-server/test/xi2/protocol-xiquerypointer.c @@ -201,6 +201,10 @@ test_XIQueryPointer(void) test_data.dev = devices.mouse; request.deviceid = devices.mouse->id; request_XIQueryPointer(&client_request, &request, Success); + + /* test REQUEST_SIZE_MATCH */ + client_request.req_len -= 4; + request_XIQueryPointer(&client_request, &request, BadLength); } int diff --git a/xorg-server/test/xi2/protocol-xiwarppointer.c b/xorg-server/test/xi2/protocol-xiwarppointer.c index f7986c1eb..3aaaae6f9 100644 --- a/xorg-server/test/xi2/protocol-xiwarppointer.c +++ b/xorg-server/test/xi2/protocol-xiwarppointer.c @@ -198,6 +198,9 @@ test_XIWarpPointer(void) request_XIWarpPointer(&client_request, &request, Success); /* FIXME: src_x/y checks */ + + client_request.req_len -= 2; /* invalid length */ + request_XIWarpPointer(&client_request, &request, BadLength); } int -- cgit v1.2.3