From 0fd9596437a827b198e323235f1033bc5150cae6 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Dec 11 2014 17:31:02 +0000 Subject: import xorg-x11-server-1.15.0-7.el7_0.3 --- diff --git a/SOURCES/0001-Missing-parens-in-REQUEST_FIXED_SIZE-macro-CVE-2014-.patch b/SOURCES/0001-Missing-parens-in-REQUEST_FIXED_SIZE-macro-CVE-2014-.patch new file mode 100644 index 0000000..ea5a3a3 --- /dev/null +++ b/SOURCES/0001-Missing-parens-in-REQUEST_FIXED_SIZE-macro-CVE-2014-.patch @@ -0,0 +1,32 @@ +From 9802a0162f738de03585ca3f3b8a8266494f7d45 Mon Sep 17 00:00:00 2001 +From: Keith Packard +Date: Tue, 9 Dec 2014 09:30:59 -0800 +Subject: [PATCH 1/2] Missing parens in REQUEST_FIXED_SIZE macro [CVE-2014-8092 + pt. 5] + +The 'n' parameter must be surrounded by parens in both places to +prevent precedence from mis-computing things. + +Signed-off-by: Keith Packard +Reviewed-by: Alan Coopersmith +Signed-off-by: Alan Coopersmith +--- + include/dix.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/dix.h b/include/dix.h +index 21176a8..921156b 100644 +--- a/include/dix.h ++++ b/include/dix.h +@@ -80,7 +80,7 @@ SOFTWARE. + + #define REQUEST_FIXED_SIZE(req, n)\ + if (((sizeof(req) >> 2) > client->req_len) || \ +- ((n >> 2) >= client->req_len) || \ ++ (((n) >> 2) >= client->req_len) || \ + ((((uint64_t) sizeof(req) + (n) + 3) >> 2) != (uint64_t) client->req_len)) \ + return(BadLength) + +-- +2.1.0 + diff --git a/SOURCES/0001-glx-check-return-from-__glXGetAnswerBuffer.patch b/SOURCES/0001-glx-check-return-from-__glXGetAnswerBuffer.patch new file mode 100644 index 0000000..cff6387 --- /dev/null +++ b/SOURCES/0001-glx-check-return-from-__glXGetAnswerBuffer.patch @@ -0,0 +1,188 @@ +From 61a292adf45405641de1c522a04c148e0a152acd Mon Sep 17 00:00:00 2001 +From: Keith Packard +Date: Thu, 9 Oct 2014 15:17:17 +0200 +Subject: [PATCH] glx: check return from __glXGetAnswerBuffer + +This function can return NULL; make sure every caller tests for that. + +Reviewed-by: Adam Jackson +Signed-off-by: Keith Packard +--- + glx/indirect_dispatch.c | 25 +++++++++++++++++++++++++ + glx/indirect_dispatch_swap.c | 26 ++++++++++++++++++++++++++ + 2 files changed, 51 insertions(+) + +diff --git a/glx/indirect_dispatch.c b/glx/indirect_dispatch.c +index 329b2e6..f6cabef 100644 +--- a/glx/indirect_dispatch.c ++++ b/glx/indirect_dispatch.c +@@ -2464,6 +2464,9 @@ __glXDisp_AreTexturesResident(__GLXclientState * cl, GLbyte * pc) + GLboolean answerBuffer[200]; + GLboolean *residences = + __glXGetAnswerBuffer(cl, n, answerBuffer, sizeof(answerBuffer), 1); ++ ++ if (residences == NULL) ++ return BadAlloc; + retval = + glAreTexturesResident(n, (const GLuint *) (pc + 4), residences); + __glXSendReply(cl->client, residences, n, 1, GL_TRUE, retval); +@@ -2488,6 +2491,9 @@ __glXDisp_AreTexturesResidentEXT(__GLXclientState * cl, GLbyte * pc) + GLboolean answerBuffer[200]; + GLboolean *residences = + __glXGetAnswerBuffer(cl, n, answerBuffer, sizeof(answerBuffer), 1); ++ ++ if (residences == NULL) ++ return BadAlloc; + retval = + glAreTexturesResident(n, (const GLuint *) (pc + 4), residences); + __glXSendReply(cl->client, residences, n, 1, GL_TRUE, retval); +@@ -2593,6 +2599,9 @@ __glXDisp_GenTextures(__GLXclientState * cl, GLbyte * pc) + GLuint *textures = + __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), + 4); ++ ++ if (textures == NULL) ++ return BadAlloc; + glGenTextures(n, textures); + __glXSendReply(cl->client, textures, n, 4, GL_TRUE, 0); + error = Success; +@@ -2616,6 +2625,9 @@ __glXDisp_GenTexturesEXT(__GLXclientState * cl, GLbyte * pc) + GLuint *textures = + __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), + 4); ++ ++ if (textures == NULL) ++ return BadAlloc; + glGenTextures(n, textures); + __glXSendReply(cl->client, textures, n, 4, GL_TRUE, 0); + error = Success; +@@ -3883,6 +3895,9 @@ __glXDisp_GenQueries(__GLXclientState * cl, GLbyte * pc) + GLuint *ids = + __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), + 4); ++ ++ if (ids == NULL) ++ return BadAlloc; + GenQueries(n, ids); + __glXSendReply(cl->client, ids, n, 4, GL_TRUE, 0); + error = Success; +@@ -4253,6 +4268,9 @@ __glXDisp_GenProgramsARB(__GLXclientState * cl, GLbyte * pc) + GLuint *programs = + __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), + 4); ++ ++ if (programs == NULL) ++ return BadAlloc; + GenProgramsARB(n, programs); + __glXSendReply(cl->client, programs, n, 4, GL_TRUE, 0); + error = Success; +@@ -4630,6 +4648,10 @@ __glXDisp_GenFramebuffers(__GLXclientState * cl, GLbyte * pc) + GLuint *framebuffers = + __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), + 4); ++ ++ if (framebuffers == NULL) ++ return BadAlloc; ++ + GenFramebuffers(n, framebuffers); + __glXSendReply(cl->client, framebuffers, n, 4, GL_TRUE, 0); + error = Success; +@@ -4655,6 +4677,9 @@ __glXDisp_GenRenderbuffers(__GLXclientState * cl, GLbyte * pc) + GLuint *renderbuffers = + __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), + 4); ++ ++ if (renderbuffers == NULL) ++ return BadAlloc; + GenRenderbuffers(n, renderbuffers); + __glXSendReply(cl->client, renderbuffers, n, 4, GL_TRUE, 0); + error = Success; +diff --git a/glx/indirect_dispatch_swap.c b/glx/indirect_dispatch_swap.c +index 647d0c9..c0bb64d 100644 +--- a/glx/indirect_dispatch_swap.c ++++ b/glx/indirect_dispatch_swap.c +@@ -2731,6 +2731,9 @@ __glXDispSwap_AreTexturesResident(__GLXclientState * cl, GLbyte * pc) + GLboolean answerBuffer[200]; + GLboolean *residences = + __glXGetAnswerBuffer(cl, n, answerBuffer, sizeof(answerBuffer), 1); ++ ++ if (residences == NULL) ++ return BadAlloc; + retval = + glAreTexturesResident(n, + (const GLuint *) +@@ -2759,6 +2762,9 @@ __glXDispSwap_AreTexturesResidentEXT(__GLXclientState * cl, GLbyte * pc) + GLboolean answerBuffer[200]; + GLboolean *residences = + __glXGetAnswerBuffer(cl, n, answerBuffer, sizeof(answerBuffer), 1); ++ ++ if (residences == NULL) ++ return BadAlloc; + retval = + glAreTexturesResident(n, + (const GLuint *) +@@ -2878,6 +2884,9 @@ __glXDispSwap_GenTextures(__GLXclientState * cl, GLbyte * pc) + GLuint *textures = + __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), + 4); ++ ++ if (textures == NULL) ++ return BadAlloc; + glGenTextures(n, textures); + (void) bswap_32_array((uint32_t *) textures, n); + __glXSendReplySwap(cl->client, textures, n, 4, GL_TRUE, 0); +@@ -2903,6 +2912,9 @@ __glXDispSwap_GenTexturesEXT(__GLXclientState * cl, GLbyte * pc) + GLuint *textures = + __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), + 4); ++ ++ if (textures == NULL) ++ return BadAlloc; + glGenTextures(n, textures); + (void) bswap_32_array((uint32_t *) textures, n); + __glXSendReplySwap(cl->client, textures, n, 4, GL_TRUE, 0); +@@ -4290,6 +4302,9 @@ __glXDispSwap_GenQueries(__GLXclientState * cl, GLbyte * pc) + GLuint *ids = + __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), + 4); ++ if (ids == NULL) ++ return BadAlloc; ++ + GenQueries(n, ids); + (void) bswap_32_array((uint32_t *) ids, n); + __glXSendReplySwap(cl->client, ids, n, 4, GL_TRUE, 0); +@@ -4697,6 +4712,9 @@ __glXDispSwap_GenProgramsARB(__GLXclientState * cl, GLbyte * pc) + GLuint *programs = + __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), + 4); ++ if (programs == NULL) ++ return BadAlloc; ++ + GenProgramsARB(n, programs); + (void) bswap_32_array((uint32_t *) programs, n); + __glXSendReplySwap(cl->client, programs, n, 4, GL_TRUE, 0); +@@ -5122,6 +5140,10 @@ __glXDispSwap_GenFramebuffers(__GLXclientState * cl, GLbyte * pc) + GLuint *framebuffers = + __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), + 4); ++ ++ if (framebuffers == NULL) ++ return BadAlloc; ++ + GenFramebuffers(n, framebuffers); + (void) bswap_32_array((uint32_t *) framebuffers, n); + __glXSendReplySwap(cl->client, framebuffers, n, 4, GL_TRUE, 0); +@@ -5149,6 +5171,10 @@ __glXDispSwap_GenRenderbuffers(__GLXclientState * cl, GLbyte * pc) + GLuint *renderbuffers = + __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), + 4); ++ ++ if (renderbuffers == NULL) ++ return BadAlloc; ++ + GenRenderbuffers(n, renderbuffers); + (void) bswap_32_array((uint32_t *) renderbuffers, n); + __glXSendReplySwap(cl->client, renderbuffers, n, 4, GL_TRUE, 0); +-- +1.9.3 + diff --git a/SOURCES/0001-unchecked-malloc-may-allow-unauthed-client-to-crash-.patch b/SOURCES/0001-unchecked-malloc-may-allow-unauthed-client-to-crash-.patch new file mode 100644 index 0000000..d6df2b3 --- /dev/null +++ b/SOURCES/0001-unchecked-malloc-may-allow-unauthed-client-to-crash-.patch @@ -0,0 +1,41 @@ +From a6eac4b0e8c615176ad43dccc353e667023e2d6e Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Fri, 17 Jan 2014 18:54:03 -0800 +Subject: [PATCH 01/33] unchecked malloc may allow unauthed client to crash + Xserver [CVE-2014-8091] + +authdes_ezdecode() calls malloc() using a length provided by the +connection handshake sent by a newly connected client in order +to authenticate to the server, so should be treated as untrusted. + +It didn't check if malloc() failed before writing to the newly +allocated buffer, so could lead to a server crash if the server +fails to allocate memory (up to UINT16_MAX bytes, since the len +field is a CARD16 in the X protocol). + +Reported-by: Ilja Van Sprundel +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +Signed-off-by: Fedora X Ninjas +--- + os/rpcauth.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/os/rpcauth.c b/os/rpcauth.c +index bd219ac..c5bf787 100644 +--- a/os/rpcauth.c ++++ b/os/rpcauth.c +@@ -66,6 +66,10 @@ authdes_ezdecode(const char *inmsg, int len) + SVCXPRT xprt; + + temp_inmsg = malloc(len); ++ if (temp_inmsg == NULL) { ++ why = AUTH_FAILED; /* generic error, since there is no AUTH_BADALLOC */ ++ return NULL; ++ } + memmove(temp_inmsg, inmsg, len); + + memset((char *) &msg, 0, sizeof(msg)); +-- +1.9.3 + diff --git a/SOURCES/0002-dix-GetHosts-bounds-check-using-wrong-pointer-value-.patch b/SOURCES/0002-dix-GetHosts-bounds-check-using-wrong-pointer-value-.patch new file mode 100644 index 0000000..c75c0a8 --- /dev/null +++ b/SOURCES/0002-dix-GetHosts-bounds-check-using-wrong-pointer-value-.patch @@ -0,0 +1,35 @@ +From 1559a94395258fd73e369f1a2c98a44bfe21a486 Mon Sep 17 00:00:00 2001 +From: Keith Packard +Date: Tue, 9 Dec 2014 09:31:00 -0800 +Subject: [PATCH 2/2] dix: GetHosts bounds check using wrong pointer value + [CVE-2014-8092 pt. 6] + +GetHosts saves the pointer to allocated memory in *data, and then +wants to bounds-check writes to that region, but was mistakenly using +a bare 'data' instead of '*data'. Also, data is declared as void **, +so we need a cast to turn it into a byte pointer so we can actually do +pointer comparisons. + +Signed-off-by: Keith Packard +Reviewed-by: Alan Coopersmith +Signed-off-by: Alan Coopersmith +--- + os/access.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/os/access.c b/os/access.c +index f393c8d..28f2d32 100644 +--- a/os/access.c ++++ b/os/access.c +@@ -1308,7 +1308,7 @@ GetHosts(void **data, int *pnHosts, int *pLen, BOOL * pEnabled) + } + for (host = validhosts; host; host = host->next) { + len = host->len; +- if ((ptr + sizeof(xHostEntry) + len) > (data + n)) ++ if ((ptr + sizeof(xHostEntry) + len) > ((unsigned char *) *data + n)) + break; + ((xHostEntry *) ptr)->family = host->family; + ((xHostEntry *) ptr)->length = len; +-- +2.1.0 + diff --git a/SOURCES/0002-dix-integer-overflow-in-ProcPutImage-CVE-2014-8092-1.patch b/SOURCES/0002-dix-integer-overflow-in-ProcPutImage-CVE-2014-8092-1.patch new file mode 100644 index 0000000..c03babe --- /dev/null +++ b/SOURCES/0002-dix-integer-overflow-in-ProcPutImage-CVE-2014-8092-1.patch @@ -0,0 +1,38 @@ +From e36af2fb51fc170ff6ca2565b6bbe1ef772741d9 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Wed, 22 Jan 2014 21:11:16 -0800 +Subject: [PATCH 02/33] dix: integer overflow in ProcPutImage() [CVE-2014-8092 + 1/4] + +ProcPutImage() calculates a length field from a width, left pad and depth +specified by the client (if the specified format is XYPixmap). + +The calculations for the total amount of memory the server needs for the +pixmap can overflow a 32-bit number, causing out-of-bounds memory writes +on 32-bit systems (since the length is stored in a long int variable). + +Reported-by: Ilja Van Sprundel +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +Signed-off-by: Fedora X Ninjas +--- + dix/dispatch.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/dix/dispatch.c b/dix/dispatch.c +index 8dcd9cb..94f262c 100644 +--- a/dix/dispatch.c ++++ b/dix/dispatch.c +@@ -1957,6 +1957,9 @@ ProcPutImage(ClientPtr client) + tmpImage = (char *) &stuff[1]; + lengthProto = length; + ++ if (lengthProto >= (INT32_MAX / stuff->height)) ++ return BadLength; ++ + if ((bytes_to_int32(lengthProto * stuff->height) + + bytes_to_int32(sizeof(xPutImageReq))) != client->req_len) + return BadLength; +-- +1.9.3 + diff --git a/SOURCES/0003-dix-integer-overflow-in-GetHosts-CVE-2014-8092-2-4.patch b/SOURCES/0003-dix-integer-overflow-in-GetHosts-CVE-2014-8092-2-4.patch new file mode 100644 index 0000000..2f3a9e1 --- /dev/null +++ b/SOURCES/0003-dix-integer-overflow-in-GetHosts-CVE-2014-8092-2-4.patch @@ -0,0 +1,50 @@ +From 014672abf617b4d0585640cdd56ce11cfb51800a Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Mon, 6 Jan 2014 23:30:14 -0800 +Subject: [PATCH 03/33] dix: integer overflow in GetHosts() [CVE-2014-8092 2/4] + +GetHosts() iterates over all the hosts it has in memory, and copies +them to a buffer. The buffer length is calculated by iterating over +all the hosts and adding up all of their combined length. There is a +potential integer overflow, if there are lots and lots of hosts (with +a combined length of > ~4 gig). This should be possible by repeatedly +calling ProcChangeHosts() on 64bit machines with enough memory. + +This patch caps the list at 1mb, because multi-megabyte hostname +lists for X access control are insane. + +Reported-by: Ilja Van Sprundel +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +Signed-off-by: Fedora X Ninjas +--- + os/access.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/os/access.c b/os/access.c +index 6d991b3..dc12348 100644 +--- a/os/access.c ++++ b/os/access.c +@@ -1323,6 +1323,10 @@ GetHosts(pointer *data, int *pnHosts, int *pLen, BOOL * pEnabled) + for (host = validhosts; host; host = host->next) { + nHosts++; + n += pad_to_int32(host->len) + sizeof(xHostEntry); ++ /* Could check for INT_MAX, but in reality having more than 1mb of ++ hostnames in the access list is ridiculous */ ++ if (n >= 1048576) ++ break; + } + if (n) { + *data = ptr = malloc(n); +@@ -1331,6 +1335,8 @@ GetHosts(pointer *data, int *pnHosts, int *pLen, BOOL * pEnabled) + } + for (host = validhosts; host; host = host->next) { + len = host->len; ++ if ((ptr + sizeof(xHostEntry) + len) > (data + n)) ++ break; + ((xHostEntry *) ptr)->family = host->family; + ((xHostEntry *) ptr)->length = len; + ptr += sizeof(xHostEntry); +-- +1.9.3 + diff --git a/SOURCES/0004-dix-integer-overflow-in-RegionSizeof-CVE-2014-8092-3.patch b/SOURCES/0004-dix-integer-overflow-in-RegionSizeof-CVE-2014-8092-3.patch new file mode 100644 index 0000000..98e1a7b --- /dev/null +++ b/SOURCES/0004-dix-integer-overflow-in-RegionSizeof-CVE-2014-8092-3.patch @@ -0,0 +1,129 @@ +From eb6ed19fb89996cf630259ba474c186d35993799 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Wed, 22 Jan 2014 22:37:15 -0800 +Subject: [PATCH 04/33] dix: integer overflow in RegionSizeof() [CVE-2014-8092 + 3/4] + +RegionSizeof contains several integer overflows if a large length +value is passed in. Once we fix it to return 0 on overflow, we +also have to fix the callers to handle this error condition + +v2: Fixed limit calculation in RegionSizeof as pointed out by jcristau. + +Reported-by: Ilja Van Sprundel +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +Reviewed-by: Julien Cristau +Signed-off-by: Fedora X Ninjas +--- + dix/region.c | 20 +++++++++++++------- + include/regionstr.h | 10 +++++++--- + 2 files changed, 20 insertions(+), 10 deletions(-) + +diff --git a/dix/region.c b/dix/region.c +index 15f3d01..e5eed01 100644 +--- a/dix/region.c ++++ b/dix/region.c +@@ -169,7 +169,6 @@ Equipment Corporation. + ((r1)->y1 <= (r2)->y1) && \ + ((r1)->y2 >= (r2)->y2) ) + +-#define xallocData(n) malloc(RegionSizeof(n)) + #define xfreeData(reg) if ((reg)->data && (reg)->data->size) free((reg)->data) + + #define RECTALLOC_BAIL(pReg,n,bail) \ +@@ -205,8 +204,9 @@ if (!(pReg)->data || (((pReg)->data->numRects + (n)) > (pReg)->data->size)) \ + #define DOWNSIZE(reg,numRects) \ + if (((numRects) < ((reg)->data->size >> 1)) && ((reg)->data->size > 50)) \ + { \ +- RegDataPtr NewData; \ +- NewData = (RegDataPtr)realloc((reg)->data, RegionSizeof(numRects)); \ ++ size_t NewSize = RegionSizeof(numRects); \ ++ RegDataPtr NewData = \ ++ (NewSize > 0) ? realloc((reg)->data, NewSize) : NULL ; \ + if (NewData) \ + { \ + NewData->size = (numRects); \ +@@ -345,17 +345,20 @@ Bool + RegionRectAlloc(RegionPtr pRgn, int n) + { + RegDataPtr data; ++ size_t rgnSize; + + if (!pRgn->data) { + n++; +- pRgn->data = xallocData(n); ++ rgnSize = RegionSizeof(n); ++ pRgn->data = (rgnSize > 0) ? malloc(rgnSize) : NULL; + if (!pRgn->data) + return RegionBreak(pRgn); + pRgn->data->numRects = 1; + *RegionBoxptr(pRgn) = pRgn->extents; + } + else if (!pRgn->data->size) { +- pRgn->data = xallocData(n); ++ rgnSize = RegionSizeof(n); ++ pRgn->data = (rgnSize > 0) ? malloc(rgnSize) : NULL; + if (!pRgn->data) + return RegionBreak(pRgn); + pRgn->data->numRects = 0; +@@ -367,7 +370,8 @@ RegionRectAlloc(RegionPtr pRgn, int n) + n = 250; + } + n += pRgn->data->numRects; +- data = (RegDataPtr) realloc(pRgn->data, RegionSizeof(n)); ++ rgnSize = RegionSizeof(n); ++ data = (rgnSize > 0) ? realloc(pRgn->data, rgnSize) : NULL; + if (!data) + return RegionBreak(pRgn); + pRgn->data = data; +@@ -1312,6 +1316,7 @@ RegionFromRects(int nrects, xRectangle *prect, int ctype) + { + + RegionPtr pRgn; ++ size_t rgnSize; + RegDataPtr pData; + BoxPtr pBox; + int i; +@@ -1338,7 +1343,8 @@ RegionFromRects(int nrects, xRectangle *prect, int ctype) + } + return pRgn; + } +- pData = xallocData(nrects); ++ rgnSize = RegionSizeof(nrects); ++ pData = (rgnSize > 0) ? malloc(rgnSize) : NULL; + if (!pData) { + RegionBreak(pRgn); + return pRgn; +diff --git a/include/regionstr.h b/include/regionstr.h +index 4a0725d..33df87f 100644 +--- a/include/regionstr.h ++++ b/include/regionstr.h +@@ -127,7 +127,10 @@ RegionEnd(RegionPtr reg) + static inline size_t + RegionSizeof(int n) + { +- return (sizeof(RegDataRec) + ((n) * sizeof(BoxRec))); ++ if (n < ((INT_MAX - sizeof(RegDataRec)) / sizeof(BoxRec))) ++ return (sizeof(RegDataRec) + ((n) * sizeof(BoxRec))); ++ else ++ return 0; + } + + static inline void +@@ -138,9 +141,10 @@ RegionInit(RegionPtr _pReg, BoxPtr _rect, int _size) + (_pReg)->data = (RegDataPtr) NULL; + } + else { ++ size_t rgnSize; + (_pReg)->extents = RegionEmptyBox; +- if (((_size) > 1) && ((_pReg)->data = +- (RegDataPtr) malloc(RegionSizeof(_size)))) { ++ if (((_size) > 1) && ((rgnSize = RegionSizeof(_size)) > 0) && ++ (((_pReg)->data = malloc(rgnSize)) != NULL)) { + (_pReg)->data->size = (_size); + (_pReg)->data->numRects = 0; + } +-- +1.9.3 + diff --git a/SOURCES/0005-dix-integer-overflow-in-REQUEST_FIXED_SIZE-CVE-2014-.patch b/SOURCES/0005-dix-integer-overflow-in-REQUEST_FIXED_SIZE-CVE-2014-.patch new file mode 100644 index 0000000..7142e87 --- /dev/null +++ b/SOURCES/0005-dix-integer-overflow-in-REQUEST_FIXED_SIZE-CVE-2014-.patch @@ -0,0 +1,35 @@ +From 0e80157d06ab07ac4535448f84eec94c52716bb4 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Wed, 22 Jan 2014 23:44:46 -0800 +Subject: [PATCH 05/33] dix: integer overflow in REQUEST_FIXED_SIZE() + [CVE-2014-8092 4/4] + +Force use of 64-bit integers when evaluating data provided by clients +in 32-bit fields which can overflow when added or multiplied during +checks. + +Reported-by: Ilja Van Sprundel +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +Signed-off-by: Fedora X Ninjas +--- + include/dix.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/include/dix.h b/include/dix.h +index fa7ccd4..7c36932 100644 +--- a/include/dix.h ++++ b/include/dix.h +@@ -76,7 +76,8 @@ SOFTWARE. + + #define REQUEST_FIXED_SIZE(req, n)\ + if (((sizeof(req) >> 2) > client->req_len) || \ +- (((sizeof(req) + (n) + 3) >> 2) != client->req_len)) \ ++ ((n >> 2) >= client->req_len) || \ ++ ((((uint64_t) sizeof(req) + (n) + 3) >> 2) != (uint64_t) client->req_len)) \ + return(BadLength) + + #define LEGAL_NEW_RESOURCE(id,client)\ +-- +1.9.3 + diff --git a/SOURCES/0006-dri2-integer-overflow-in-ProcDRI2GetBuffers-CVE-2014.patch b/SOURCES/0006-dri2-integer-overflow-in-ProcDRI2GetBuffers-CVE-2014.patch new file mode 100644 index 0000000..570a0bc --- /dev/null +++ b/SOURCES/0006-dri2-integer-overflow-in-ProcDRI2GetBuffers-CVE-2014.patch @@ -0,0 +1,36 @@ +From 7cadf50d0b2f036ddaf9d4d93405fd68bbe53f2a Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Wed, 22 Jan 2014 23:40:18 -0800 +Subject: [PATCH 06/33] dri2: integer overflow in ProcDRI2GetBuffers() + [CVE-2014-8094] + +ProcDRI2GetBuffers() tries to validate a length field (count). +There is an integer overflow in the validation. This can cause +out of bound reads and memory corruption later on. + +Reported-by: Ilja Van Sprundel +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +Reviewed-by: Julien Cristau +Signed-off-by: Fedora X Ninjas +--- + hw/xfree86/dri2/dri2ext.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c +index b858213..b70624e 100644 +--- a/hw/xfree86/dri2/dri2ext.c ++++ b/hw/xfree86/dri2/dri2ext.c +@@ -281,6 +281,9 @@ ProcDRI2GetBuffers(ClientPtr client) + unsigned int *attachments; + + REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * 4); ++ if (stuff->count > (INT_MAX / 4)) ++ return BadLength; ++ + if (!validDrawable(client, stuff->drawable, DixReadAccess | DixWriteAccess, + &pDrawable, &status)) + return status; +-- +1.9.3 + diff --git a/SOURCES/0007-dbe-unvalidated-lengths-in-DbeSwapBuffers-calls-CVE-.patch b/SOURCES/0007-dbe-unvalidated-lengths-in-DbeSwapBuffers-calls-CVE-.patch new file mode 100644 index 0000000..b9bf6e0 --- /dev/null +++ b/SOURCES/0007-dbe-unvalidated-lengths-in-DbeSwapBuffers-calls-CVE-.patch @@ -0,0 +1,74 @@ +From 5c37a8a720a39c881fe8e5ee59de1e570f9ce01d Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Wed, 22 Jan 2014 23:12:04 -0800 +Subject: [PATCH 07/33] dbe: unvalidated lengths in DbeSwapBuffers calls + [CVE-2014-8097] + +ProcDbeSwapBuffers() has a 32bit (n) length value that it uses to read +from a buffer. The length is never validated, which can lead to out of +bound reads, and possibly returning the data read from out of bounds to +the misbehaving client via an X Error packet. + +SProcDbeSwapBuffers() swaps data (for correct endianness) before +handing it off to the real proc. While doing the swapping, the +length field is not validated, which can cause memory corruption. + +v2: reorder checks to avoid compilers optimizing out checks for overflow +that happen after we'd already have done the overflowing multiplications. + +Reported-by: Ilja Van Sprundel +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +Signed-off-by: Fedora X Ninjas +--- + dbe/dbe.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/dbe/dbe.c b/dbe/dbe.c +index 8d8bfb9..9be5297 100644 +--- a/dbe/dbe.c ++++ b/dbe/dbe.c +@@ -450,18 +450,20 @@ ProcDbeSwapBuffers(ClientPtr client) + DbeSwapInfoPtr swapInfo; + xDbeSwapInfo *dbeSwapInfo; + int error; +- register int i, j; +- int nStuff; ++ unsigned int i, j; ++ unsigned int nStuff; + + REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq); + nStuff = stuff->n; /* use local variable for performance. */ + + if (nStuff == 0) { ++ REQUEST_SIZE_MATCH(xDbeSwapBuffersReq); + return Success; + } + + if (nStuff > UINT32_MAX / sizeof(DbeSwapInfoRec)) + return BadAlloc; ++ REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, nStuff * sizeof(xDbeSwapInfo)); + + /* Get to the swap info appended to the end of the request. */ + dbeSwapInfo = (xDbeSwapInfo *) & stuff[1]; +@@ -914,13 +916,16 @@ static int + SProcDbeSwapBuffers(ClientPtr client) + { + REQUEST(xDbeSwapBuffersReq); +- register int i; ++ unsigned int i; + xDbeSwapInfo *pSwapInfo; + + swaps(&stuff->length); + REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq); + + swapl(&stuff->n); ++ if (stuff->n > UINT32_MAX / sizeof(DbeSwapInfoRec)) ++ return BadAlloc; ++ REQUEST_FIXED_SIZE(xDbeSwapBuffersReq, stuff->n * sizeof(xDbeSwapInfo)); + + if (stuff->n != 0) { + pSwapInfo = (xDbeSwapInfo *) stuff + 1; +-- +1.9.3 + diff --git a/SOURCES/0008-Xi-unvalidated-lengths-in-Xinput-extension-CVE-2014-.patch b/SOURCES/0008-Xi-unvalidated-lengths-in-Xinput-extension-CVE-2014-.patch new file mode 100644 index 0000000..e798a68 --- /dev/null +++ b/SOURCES/0008-Xi-unvalidated-lengths-in-Xinput-extension-CVE-2014-.patch @@ -0,0 +1,552 @@ +From 757fe009c45278807d6951d6380292de9133f0f8 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 26 Jan 2014 10:54:41 -0800 +Subject: [PATCH 08/33] Xi: unvalidated lengths in Xinput extension + [CVE-2014-8095] + +Multiple functions in the Xinput extension handling of requests from +clients failed to check that the length of the request sent by the +client was large enough to perform all the required operations and +thus could read or write to memory outside the bounds of the request +buffer. + +This commit includes the creation of a new REQUEST_AT_LEAST_EXTRA_SIZE +macro in include/dix.h for the common case of needing to ensure a +request is large enough to include both the request itself and a +minimum amount of extra data following the request header. + +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +Signed-off-by: Fedora X Ninjas +--- + Xi/chgdctl.c | 8 ++++++-- + Xi/chgfctl.c | 2 ++ + Xi/sendexev.c | 3 +++ + Xi/xiallowev.c | 2 ++ + Xi/xichangecursor.c | 2 +- + Xi/xichangehierarchy.c | 35 ++++++++++++++++++++++++++++++++--- + Xi/xigetclientpointer.c | 1 + + Xi/xigrabdev.c | 9 ++++++++- + Xi/xipassivegrab.c | 12 ++++++++++-- + Xi/xiproperty.c | 14 ++++++-------- + Xi/xiquerydevice.c | 1 + + Xi/xiquerypointer.c | 2 ++ + Xi/xiselectev.c | 8 ++++++++ + Xi/xisetclientpointer.c | 3 ++- + Xi/xisetdevfocus.c | 4 ++++ + Xi/xiwarppointer.c | 2 ++ + include/dix.h | 4 ++++ + 17 files changed, 94 insertions(+), 18 deletions(-) + +diff --git a/Xi/chgdctl.c b/Xi/chgdctl.c +index d078aa2..b3ee867 100644 +--- a/Xi/chgdctl.c ++++ b/Xi/chgdctl.c +@@ -78,7 +78,7 @@ SProcXChangeDeviceControl(ClientPtr client) + + REQUEST(xChangeDeviceControlReq); + swaps(&stuff->length); +- REQUEST_AT_LEAST_SIZE(xChangeDeviceControlReq); ++ REQUEST_AT_LEAST_EXTRA_SIZE(xChangeDeviceControlReq, sizeof(xDeviceCtl)); + swaps(&stuff->control); + ctl = (xDeviceCtl *) &stuff[1]; + swaps(&ctl->control); +@@ -115,7 +115,7 @@ ProcXChangeDeviceControl(ClientPtr client) + xDeviceEnableCtl *e; + + REQUEST(xChangeDeviceControlReq); +- REQUEST_AT_LEAST_SIZE(xChangeDeviceControlReq); ++ REQUEST_AT_LEAST_EXTRA_SIZE(xChangeDeviceControlReq, sizeof(xDeviceCtl)); + + len = stuff->length - bytes_to_int32(sizeof(xChangeDeviceControlReq)); + ret = dixLookupDevice(&dev, stuff->deviceid, client, DixManageAccess); +@@ -192,6 +192,10 @@ ProcXChangeDeviceControl(ClientPtr client) + break; + case DEVICE_ENABLE: + e = (xDeviceEnableCtl *) &stuff[1]; ++ if ((len != bytes_to_int32(sizeof(xDeviceEnableCtl)))) { ++ ret = BadLength; ++ goto out; ++ } + + if (IsXTestDevice(dev, NULL)) + status = !Success; +diff --git a/Xi/chgfctl.c b/Xi/chgfctl.c +index 6dcf60c..224c2ba 100644 +--- a/Xi/chgfctl.c ++++ b/Xi/chgfctl.c +@@ -467,6 +467,8 @@ ProcXChangeFeedbackControl(ClientPtr client) + xStringFeedbackCtl *f = ((xStringFeedbackCtl *) &stuff[1]); + + if (client->swapped) { ++ if (len < bytes_to_int32(sizeof(xStringFeedbackCtl))) ++ return BadLength; + swaps(&f->num_keysyms); + } + if (len != +diff --git a/Xi/sendexev.c b/Xi/sendexev.c +index 3c21386..183f88d 100644 +--- a/Xi/sendexev.c ++++ b/Xi/sendexev.c +@@ -135,6 +135,9 @@ ProcXSendExtensionEvent(ClientPtr client) + if (ret != Success) + return ret; + ++ if (stuff->num_events == 0) ++ return ret; ++ + /* The client's event type must be one defined by an extension. */ + + first = ((xEvent *) &stuff[1]); +diff --git a/Xi/xiallowev.c b/Xi/xiallowev.c +index ebef233..ca263ef 100644 +--- a/Xi/xiallowev.c ++++ b/Xi/xiallowev.c +@@ -48,6 +48,7 @@ int + SProcXIAllowEvents(ClientPtr client) + { + REQUEST(xXIAllowEventsReq); ++ REQUEST_AT_LEAST_SIZE(xXIAllowEventsReq); + + swaps(&stuff->length); + swaps(&stuff->deviceid); +@@ -55,6 +56,7 @@ SProcXIAllowEvents(ClientPtr client) + if (stuff->length > 3) { + xXI2_2AllowEventsReq *req_xi22 = (xXI2_2AllowEventsReq *) stuff; + ++ REQUEST_AT_LEAST_SIZE(xXI2_2AllowEventsReq); + swapl(&req_xi22->touchid); + swapl(&req_xi22->grab_window); + } +diff --git a/Xi/xichangecursor.c b/Xi/xichangecursor.c +index 0be6bc0..33e9e9c 100644 +--- a/Xi/xichangecursor.c ++++ b/Xi/xichangecursor.c +@@ -57,11 +57,11 @@ int + SProcXIChangeCursor(ClientPtr client) + { + REQUEST(xXIChangeCursorReq); ++ REQUEST_SIZE_MATCH(xXIChangeCursorReq); + swaps(&stuff->length); + swapl(&stuff->win); + swapl(&stuff->cursor); + swaps(&stuff->deviceid); +- REQUEST_SIZE_MATCH(xXIChangeCursorReq); + return (ProcXIChangeCursor(client)); + } + +diff --git a/Xi/xichangehierarchy.c b/Xi/xichangehierarchy.c +index e2f4b8a..8e3415b 100644 +--- a/Xi/xichangehierarchy.c ++++ b/Xi/xichangehierarchy.c +@@ -407,7 +407,7 @@ int + ProcXIChangeHierarchy(ClientPtr client) + { + xXIAnyHierarchyChangeInfo *any; +- int required_len = sizeof(xXIChangeHierarchyReq); ++ size_t len; /* length of data remaining in request */ + int rc = Success; + int flags[MAXDEVICES] = { 0 }; + +@@ -417,21 +417,46 @@ ProcXIChangeHierarchy(ClientPtr client) + if (!stuff->num_changes) + return rc; + ++ if (stuff->length > (INT_MAX >> 2)) ++ return BadAlloc; ++ len = (stuff->length << 2) - sizeof(xXIAnyHierarchyChangeInfo); ++ + any = (xXIAnyHierarchyChangeInfo *) &stuff[1]; + while (stuff->num_changes--) { ++ if (len < sizeof(xXIAnyHierarchyChangeInfo)) { ++ rc = BadLength; ++ goto unwind; ++ } ++ + SWAPIF(swaps(&any->type)); + SWAPIF(swaps(&any->length)); + +- required_len += any->length; +- if ((stuff->length * 4) < required_len) ++ if ((any->length > (INT_MAX >> 2)) || (len < (any->length << 2))) + return BadLength; + ++#define CHANGE_SIZE_MATCH(type) \ ++ do { \ ++ if ((len < sizeof(type)) || (any->length != (sizeof(type) >> 2))) { \ ++ rc = BadLength; \ ++ goto unwind; \ ++ } \ ++ } while(0) ++ + switch (any->type) { + case XIAddMaster: + { + xXIAddMasterInfo *c = (xXIAddMasterInfo *) any; + ++ /* Variable length, due to appended name string */ ++ if (len < sizeof(xXIAddMasterInfo)) { ++ rc = BadLength; ++ goto unwind; ++ } + SWAPIF(swaps(&c->name_len)); ++ if (c->name_len > (len - sizeof(xXIAddMasterInfo))) { ++ rc = BadLength; ++ goto unwind; ++ } + + rc = add_master(client, c, flags); + if (rc != Success) +@@ -442,6 +467,7 @@ ProcXIChangeHierarchy(ClientPtr client) + { + xXIRemoveMasterInfo *r = (xXIRemoveMasterInfo *) any; + ++ CHANGE_SIZE_MATCH(xXIRemoveMasterInfo); + rc = remove_master(client, r, flags); + if (rc != Success) + goto unwind; +@@ -451,6 +477,7 @@ ProcXIChangeHierarchy(ClientPtr client) + { + xXIDetachSlaveInfo *c = (xXIDetachSlaveInfo *) any; + ++ CHANGE_SIZE_MATCH(xXIDetachSlaveInfo); + rc = detach_slave(client, c, flags); + if (rc != Success) + goto unwind; +@@ -460,6 +487,7 @@ ProcXIChangeHierarchy(ClientPtr client) + { + xXIAttachSlaveInfo *c = (xXIAttachSlaveInfo *) any; + ++ CHANGE_SIZE_MATCH(xXIAttachSlaveInfo); + rc = attach_slave(client, c, flags); + if (rc != Success) + goto unwind; +@@ -467,6 +495,7 @@ ProcXIChangeHierarchy(ClientPtr client) + break; + } + ++ len -= any->length * 4; + any = (xXIAnyHierarchyChangeInfo *) ((char *) any + any->length * 4); + } + +diff --git a/Xi/xigetclientpointer.c b/Xi/xigetclientpointer.c +index 3c90d58..306dd39 100644 +--- a/Xi/xigetclientpointer.c ++++ b/Xi/xigetclientpointer.c +@@ -50,6 +50,7 @@ int + SProcXIGetClientPointer(ClientPtr client) + { + REQUEST(xXIGetClientPointerReq); ++ REQUEST_SIZE_MATCH(xXIGetClientPointerReq); + + swaps(&stuff->length); + swapl(&stuff->win); +diff --git a/Xi/xigrabdev.c b/Xi/xigrabdev.c +index 63d95bc..e2a2ae3 100644 +--- a/Xi/xigrabdev.c ++++ b/Xi/xigrabdev.c +@@ -47,6 +47,11 @@ int + SProcXIGrabDevice(ClientPtr client) + { + REQUEST(xXIGrabDeviceReq); ++ /* ++ * Check here for at least the length of the struct we swap, then ++ * let ProcXIGrabDevice check the full size after we swap mask_len. ++ */ ++ REQUEST_AT_LEAST_SIZE(xXIGrabDeviceReq); + + swaps(&stuff->length); + swaps(&stuff->deviceid); +@@ -71,7 +76,7 @@ ProcXIGrabDevice(ClientPtr client) + unsigned int pointer_mode; + + REQUEST(xXIGrabDeviceReq); +- REQUEST_AT_LEAST_SIZE(xXIGrabDeviceReq); ++ REQUEST_FIXED_SIZE(xXIGrabDeviceReq, ((size_t) stuff->mask_len) * 4); + + ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGrabAccess); + if (ret != Success) +@@ -131,6 +136,7 @@ int + SProcXIUngrabDevice(ClientPtr client) + { + REQUEST(xXIUngrabDeviceReq); ++ REQUEST_SIZE_MATCH(xXIUngrabDeviceReq); + + swaps(&stuff->length); + swaps(&stuff->deviceid); +@@ -148,6 +154,7 @@ ProcXIUngrabDevice(ClientPtr client) + TimeStamp time; + + REQUEST(xXIUngrabDeviceReq); ++ REQUEST_SIZE_MATCH(xXIUngrabDeviceReq); + + ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess); + if (ret != Success) +diff --git a/Xi/xipassivegrab.c b/Xi/xipassivegrab.c +index eccec0a..a714a44 100644 +--- a/Xi/xipassivegrab.c ++++ b/Xi/xipassivegrab.c +@@ -53,6 +53,7 @@ SProcXIPassiveGrabDevice(ClientPtr client) + uint32_t *mods; + + REQUEST(xXIPassiveGrabDeviceReq); ++ REQUEST_AT_LEAST_SIZE(xXIPassiveGrabDeviceReq); + + swaps(&stuff->length); + swaps(&stuff->deviceid); +@@ -63,6 +64,8 @@ SProcXIPassiveGrabDevice(ClientPtr client) + swaps(&stuff->mask_len); + swaps(&stuff->num_modifiers); + ++ REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq, ++ ((uint32_t) stuff->mask_len + stuff->num_modifiers) *4); + mods = (uint32_t *) &stuff[1]; + + for (i = 0; i < stuff->num_modifiers; i++, mods++) { +@@ -92,7 +95,8 @@ ProcXIPassiveGrabDevice(ClientPtr client) + int mask_len; + + REQUEST(xXIPassiveGrabDeviceReq); +- REQUEST_AT_LEAST_SIZE(xXIPassiveGrabDeviceReq); ++ REQUEST_FIXED_SIZE(xXIPassiveGrabDeviceReq, ++ ((uint32_t) stuff->mask_len + stuff->num_modifiers) * 4); + + if (stuff->deviceid == XIAllDevices) + dev = inputInfo.all_devices; +@@ -248,6 +252,7 @@ SProcXIPassiveUngrabDevice(ClientPtr client) + uint32_t *modifiers; + + REQUEST(xXIPassiveUngrabDeviceReq); ++ REQUEST_AT_LEAST_SIZE(xXIPassiveUngrabDeviceReq); + + swaps(&stuff->length); + swapl(&stuff->grab_window); +@@ -255,6 +260,8 @@ SProcXIPassiveUngrabDevice(ClientPtr client) + swapl(&stuff->detail); + swaps(&stuff->num_modifiers); + ++ REQUEST_FIXED_SIZE(xXIPassiveUngrabDeviceReq, ++ ((uint32_t) stuff->num_modifiers) << 2); + modifiers = (uint32_t *) &stuff[1]; + + for (i = 0; i < stuff->num_modifiers; i++, modifiers++) +@@ -273,7 +280,8 @@ ProcXIPassiveUngrabDevice(ClientPtr client) + int i, rc; + + REQUEST(xXIPassiveUngrabDeviceReq); +- REQUEST_AT_LEAST_SIZE(xXIPassiveUngrabDeviceReq); ++ REQUEST_FIXED_SIZE(xXIPassiveUngrabDeviceReq, ++ ((uint32_t) stuff->num_modifiers) << 2); + + if (stuff->deviceid == XIAllDevices) + dev = inputInfo.all_devices; +diff --git a/Xi/xiproperty.c b/Xi/xiproperty.c +index 796ba09..c99e282 100644 +--- a/Xi/xiproperty.c ++++ b/Xi/xiproperty.c +@@ -1013,10 +1013,9 @@ int + SProcXListDeviceProperties(ClientPtr client) + { + REQUEST(xListDevicePropertiesReq); ++ REQUEST_SIZE_MATCH(xListDevicePropertiesReq); + + swaps(&stuff->length); +- +- REQUEST_SIZE_MATCH(xListDevicePropertiesReq); + return (ProcXListDeviceProperties(client)); + } + +@@ -1037,10 +1036,10 @@ int + SProcXDeleteDeviceProperty(ClientPtr client) + { + REQUEST(xDeleteDevicePropertyReq); ++ REQUEST_SIZE_MATCH(xDeleteDevicePropertyReq); + + swaps(&stuff->length); + swapl(&stuff->property); +- REQUEST_SIZE_MATCH(xDeleteDevicePropertyReq); + return (ProcXDeleteDeviceProperty(client)); + } + +@@ -1048,13 +1047,13 @@ int + SProcXGetDeviceProperty(ClientPtr client) + { + REQUEST(xGetDevicePropertyReq); ++ REQUEST_SIZE_MATCH(xGetDevicePropertyReq); + + swaps(&stuff->length); + swapl(&stuff->property); + swapl(&stuff->type); + swapl(&stuff->longOffset); + swapl(&stuff->longLength); +- REQUEST_SIZE_MATCH(xGetDevicePropertyReq); + return (ProcXGetDeviceProperty(client)); + } + +@@ -1253,11 +1252,10 @@ int + SProcXIListProperties(ClientPtr client) + { + REQUEST(xXIListPropertiesReq); ++ REQUEST_SIZE_MATCH(xXIListPropertiesReq); + + swaps(&stuff->length); + swaps(&stuff->deviceid); +- +- REQUEST_SIZE_MATCH(xXIListPropertiesReq); + return (ProcXIListProperties(client)); + } + +@@ -1279,11 +1277,11 @@ int + SProcXIDeleteProperty(ClientPtr client) + { + REQUEST(xXIDeletePropertyReq); ++ REQUEST_SIZE_MATCH(xXIDeletePropertyReq); + + swaps(&stuff->length); + swaps(&stuff->deviceid); + swapl(&stuff->property); +- REQUEST_SIZE_MATCH(xXIDeletePropertyReq); + return (ProcXIDeleteProperty(client)); + } + +@@ -1291,6 +1289,7 @@ int + SProcXIGetProperty(ClientPtr client) + { + REQUEST(xXIGetPropertyReq); ++ REQUEST_SIZE_MATCH(xXIGetPropertyReq); + + swaps(&stuff->length); + swaps(&stuff->deviceid); +@@ -1298,7 +1297,6 @@ SProcXIGetProperty(ClientPtr client) + swapl(&stuff->type); + swapl(&stuff->offset); + swapl(&stuff->len); +- REQUEST_SIZE_MATCH(xXIGetPropertyReq); + return (ProcXIGetProperty(client)); + } + +diff --git a/Xi/xiquerydevice.c b/Xi/xiquerydevice.c +index 4e544f0..67a9a4f 100644 +--- a/Xi/xiquerydevice.c ++++ b/Xi/xiquerydevice.c +@@ -54,6 +54,7 @@ int + SProcXIQueryDevice(ClientPtr client) + { + REQUEST(xXIQueryDeviceReq); ++ REQUEST_SIZE_MATCH(xXIQueryDeviceReq); + + swaps(&stuff->length); + swaps(&stuff->deviceid); +diff --git a/Xi/xiquerypointer.c b/Xi/xiquerypointer.c +index e9bdd42..7ec0c85 100644 +--- a/Xi/xiquerypointer.c ++++ b/Xi/xiquerypointer.c +@@ -63,6 +63,8 @@ int + SProcXIQueryPointer(ClientPtr client) + { + REQUEST(xXIQueryPointerReq); ++ REQUEST_SIZE_MATCH(xXIQueryPointerReq); ++ + swaps(&stuff->length); + swaps(&stuff->deviceid); + swapl(&stuff->win); +diff --git a/Xi/xiselectev.c b/Xi/xiselectev.c +index 45a996e..168579f 100644 +--- a/Xi/xiselectev.c ++++ b/Xi/xiselectev.c +@@ -114,6 +114,7 @@ int + SProcXISelectEvents(ClientPtr client) + { + int i; ++ int len; + xXIEventMask *evmask; + + REQUEST(xXISelectEventsReq); +@@ -122,10 +123,17 @@ SProcXISelectEvents(ClientPtr client) + swapl(&stuff->win); + swaps(&stuff->num_masks); + ++ len = stuff->length - bytes_to_int32(sizeof(xXISelectEventsReq)); + evmask = (xXIEventMask *) &stuff[1]; + for (i = 0; i < stuff->num_masks; i++) { ++ if (len < bytes_to_int32(sizeof(xXIEventMask))) ++ return BadLength; ++ len -= bytes_to_int32(sizeof(xXIEventMask)); + swaps(&evmask->deviceid); + swaps(&evmask->mask_len); ++ if (len < evmask->mask_len) ++ return BadLength; ++ len -= evmask->mask_len; + evmask = + (xXIEventMask *) (((char *) &evmask[1]) + evmask->mask_len * 4); + } +diff --git a/Xi/xisetclientpointer.c b/Xi/xisetclientpointer.c +index 38ff51e..24d4a53 100644 +--- a/Xi/xisetclientpointer.c ++++ b/Xi/xisetclientpointer.c +@@ -51,10 +51,11 @@ int + SProcXISetClientPointer(ClientPtr client) + { + REQUEST(xXISetClientPointerReq); ++ REQUEST_SIZE_MATCH(xXISetClientPointerReq); ++ + swaps(&stuff->length); + swapl(&stuff->win); + swaps(&stuff->deviceid); +- REQUEST_SIZE_MATCH(xXISetClientPointerReq); + return (ProcXISetClientPointer(client)); + } + +diff --git a/Xi/xisetdevfocus.c b/Xi/xisetdevfocus.c +index 372ec24..96a9a16 100644 +--- a/Xi/xisetdevfocus.c ++++ b/Xi/xisetdevfocus.c +@@ -44,6 +44,8 @@ int + SProcXISetFocus(ClientPtr client) + { + REQUEST(xXISetFocusReq); ++ REQUEST_AT_LEAST_SIZE(xXISetFocusReq); ++ + swaps(&stuff->length); + swaps(&stuff->deviceid); + swapl(&stuff->focus); +@@ -56,6 +58,8 @@ int + SProcXIGetFocus(ClientPtr client) + { + REQUEST(xXIGetFocusReq); ++ REQUEST_AT_LEAST_SIZE(xXIGetFocusReq); ++ + swaps(&stuff->length); + swaps(&stuff->deviceid); + +diff --git a/Xi/xiwarppointer.c b/Xi/xiwarppointer.c +index 3f051f7..780758a 100644 +--- a/Xi/xiwarppointer.c ++++ b/Xi/xiwarppointer.c +@@ -56,6 +56,8 @@ int + SProcXIWarpPointer(ClientPtr client) + { + REQUEST(xXIWarpPointerReq); ++ REQUEST_SIZE_MATCH(xXIWarpPointerReq); ++ + swaps(&stuff->length); + swapl(&stuff->src_win); + swapl(&stuff->dst_win); +diff --git a/include/dix.h b/include/dix.h +index 7c36932..72adad3 100644 +--- a/include/dix.h ++++ b/include/dix.h +@@ -74,6 +74,10 @@ SOFTWARE. + if ((sizeof(req) >> 2) > client->req_len )\ + return(BadLength) + ++#define REQUEST_AT_LEAST_EXTRA_SIZE(req, extra) \ ++ if (((sizeof(req) + ((uint64_t) extra)) >> 2) > client->req_len ) \ ++ return(BadLength) ++ + #define REQUEST_FIXED_SIZE(req, n)\ + if (((sizeof(req) >> 2) > client->req_len) || \ + ((n >> 2) >= client->req_len) || \ +-- +1.9.3 + diff --git a/SOURCES/0009-xcmisc-unvalidated-length-in-SProcXCMiscGetXIDList-C.patch b/SOURCES/0009-xcmisc-unvalidated-length-in-SProcXCMiscGetXIDList-C.patch new file mode 100644 index 0000000..354536d --- /dev/null +++ b/SOURCES/0009-xcmisc-unvalidated-length-in-SProcXCMiscGetXIDList-C.patch @@ -0,0 +1,28 @@ +From 182af4a188dcdc11228c15ce3252d1503015ced7 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 26 Jan 2014 17:18:54 -0800 +Subject: [PATCH 09/33] xcmisc: unvalidated length in SProcXCMiscGetXIDList() + [CVE-2014-8096] + +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +Signed-off-by: Fedora X Ninjas +--- + Xext/xcmisc.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Xext/xcmisc.c b/Xext/xcmisc.c +index 034bfb6..1e91010 100644 +--- a/Xext/xcmisc.c ++++ b/Xext/xcmisc.c +@@ -167,6 +167,7 @@ static int + SProcXCMiscGetXIDList(ClientPtr client) + { + REQUEST(xXCMiscGetXIDListReq); ++ REQUEST_SIZE_MATCH(xXCMiscGetXIDListReq); + + swaps(&stuff->length); + swapl(&stuff->count); +-- +1.9.3 + diff --git a/SOURCES/0010-Xv-unvalidated-lengths-in-XVideo-extension-swapped-p.patch b/SOURCES/0010-Xv-unvalidated-lengths-in-XVideo-extension-swapped-p.patch new file mode 100644 index 0000000..5b1af8b --- /dev/null +++ b/SOURCES/0010-Xv-unvalidated-lengths-in-XVideo-extension-swapped-p.patch @@ -0,0 +1,180 @@ +From 24b5c3df657bfe27db9ae21289fbdfc4f887117e Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 26 Jan 2014 19:23:17 -0800 +Subject: [PATCH 10/33] Xv: unvalidated lengths in XVideo extension swapped + procs [CVE-2014-8099] + +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +Signed-off-by: Fedora X Ninjas +--- + Xext/xvdisp.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/Xext/xvdisp.c b/Xext/xvdisp.c +index 613867a..74a12bb 100644 +--- a/Xext/xvdisp.c ++++ b/Xext/xvdisp.c +@@ -1207,6 +1207,7 @@ static int + SProcXvQueryExtension(ClientPtr client) + { + REQUEST(xvQueryExtensionReq); ++ REQUEST_SIZE_MATCH(xvQueryExtensionReq); + swaps(&stuff->length); + return XvProcVector[xv_QueryExtension] (client); + } +@@ -1215,6 +1216,7 @@ static int + SProcXvQueryAdaptors(ClientPtr client) + { + REQUEST(xvQueryAdaptorsReq); ++ REQUEST_SIZE_MATCH(xvQueryAdaptorsReq); + swaps(&stuff->length); + swapl(&stuff->window); + return XvProcVector[xv_QueryAdaptors] (client); +@@ -1224,6 +1226,7 @@ static int + SProcXvQueryEncodings(ClientPtr client) + { + REQUEST(xvQueryEncodingsReq); ++ REQUEST_SIZE_MATCH(xvQueryEncodingsReq); + swaps(&stuff->length); + swapl(&stuff->port); + return XvProcVector[xv_QueryEncodings] (client); +@@ -1233,6 +1236,7 @@ static int + SProcXvGrabPort(ClientPtr client) + { + REQUEST(xvGrabPortReq); ++ REQUEST_SIZE_MATCH(xvGrabPortReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->time); +@@ -1243,6 +1247,7 @@ static int + SProcXvUngrabPort(ClientPtr client) + { + REQUEST(xvUngrabPortReq); ++ REQUEST_SIZE_MATCH(xvUngrabPortReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->time); +@@ -1253,6 +1258,7 @@ static int + SProcXvPutVideo(ClientPtr client) + { + REQUEST(xvPutVideoReq); ++ REQUEST_SIZE_MATCH(xvPutVideoReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->drawable); +@@ -1272,6 +1278,7 @@ static int + SProcXvPutStill(ClientPtr client) + { + REQUEST(xvPutStillReq); ++ REQUEST_SIZE_MATCH(xvPutStillReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->drawable); +@@ -1291,6 +1298,7 @@ static int + SProcXvGetVideo(ClientPtr client) + { + REQUEST(xvGetVideoReq); ++ REQUEST_SIZE_MATCH(xvGetVideoReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->drawable); +@@ -1310,6 +1318,7 @@ static int + SProcXvGetStill(ClientPtr client) + { + REQUEST(xvGetStillReq); ++ REQUEST_SIZE_MATCH(xvGetStillReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->drawable); +@@ -1329,6 +1338,7 @@ static int + SProcXvPutImage(ClientPtr client) + { + REQUEST(xvPutImageReq); ++ REQUEST_AT_LEAST_SIZE(xvPutImageReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->drawable); +@@ -1352,6 +1362,7 @@ static int + SProcXvShmPutImage(ClientPtr client) + { + REQUEST(xvShmPutImageReq); ++ REQUEST_SIZE_MATCH(xvShmPutImageReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->drawable); +@@ -1379,6 +1390,7 @@ static int + SProcXvSelectVideoNotify(ClientPtr client) + { + REQUEST(xvSelectVideoNotifyReq); ++ REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq); + swaps(&stuff->length); + swapl(&stuff->drawable); + return XvProcVector[xv_SelectVideoNotify] (client); +@@ -1388,6 +1400,7 @@ static int + SProcXvSelectPortNotify(ClientPtr client) + { + REQUEST(xvSelectPortNotifyReq); ++ REQUEST_SIZE_MATCH(xvSelectPortNotifyReq); + swaps(&stuff->length); + swapl(&stuff->port); + return XvProcVector[xv_SelectPortNotify] (client); +@@ -1397,6 +1410,7 @@ static int + SProcXvStopVideo(ClientPtr client) + { + REQUEST(xvStopVideoReq); ++ REQUEST_SIZE_MATCH(xvStopVideoReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->drawable); +@@ -1407,6 +1421,7 @@ static int + SProcXvSetPortAttribute(ClientPtr client) + { + REQUEST(xvSetPortAttributeReq); ++ REQUEST_SIZE_MATCH(xvSetPortAttributeReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->attribute); +@@ -1418,6 +1433,7 @@ static int + SProcXvGetPortAttribute(ClientPtr client) + { + REQUEST(xvGetPortAttributeReq); ++ REQUEST_SIZE_MATCH(xvGetPortAttributeReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->attribute); +@@ -1428,6 +1444,7 @@ static int + SProcXvQueryBestSize(ClientPtr client) + { + REQUEST(xvQueryBestSizeReq); ++ REQUEST_SIZE_MATCH(xvQueryBestSizeReq); + swaps(&stuff->length); + swapl(&stuff->port); + swaps(&stuff->vid_w); +@@ -1441,6 +1458,7 @@ static int + SProcXvQueryPortAttributes(ClientPtr client) + { + REQUEST(xvQueryPortAttributesReq); ++ REQUEST_SIZE_MATCH(xvQueryPortAttributesReq); + swaps(&stuff->length); + swapl(&stuff->port); + return XvProcVector[xv_QueryPortAttributes] (client); +@@ -1450,6 +1468,7 @@ static int + SProcXvQueryImageAttributes(ClientPtr client) + { + REQUEST(xvQueryImageAttributesReq); ++ REQUEST_SIZE_MATCH(xvQueryImageAttributesReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->id); +@@ -1462,6 +1481,7 @@ static int + SProcXvListImageFormats(ClientPtr client) + { + REQUEST(xvListImageFormatsReq); ++ REQUEST_SIZE_MATCH(xvListImageFormatsReq); + swaps(&stuff->length); + swapl(&stuff->port); + return XvProcVector[xv_ListImageFormats] (client); +-- +1.9.3 + diff --git a/SOURCES/0011-dri3-unvalidated-lengths-in-DRI3-extension-swapped-p.patch b/SOURCES/0011-dri3-unvalidated-lengths-in-DRI3-extension-swapped-p.patch new file mode 100644 index 0000000..9039011 --- /dev/null +++ b/SOURCES/0011-dri3-unvalidated-lengths-in-DRI3-extension-swapped-p.patch @@ -0,0 +1,68 @@ +From f8d54fefd98dd2ffd8d5680a6b7b5276b683e3e0 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 26 Jan 2014 19:28:05 -0800 +Subject: [PATCH 11/33] dri3: unvalidated lengths in DRI3 extension swapped + procs [CVE-2014-8103 1/2] + +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +Signed-off-by: Fedora X Ninjas +--- + dri3/dri3_request.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/dri3/dri3_request.c b/dri3/dri3_request.c +index 4e1408f..2d05066 100644 +--- a/dri3/dri3_request.c ++++ b/dri3/dri3_request.c +@@ -311,6 +311,7 @@ static int + sproc_dri3_query_version(ClientPtr client) + { + REQUEST(xDRI3QueryVersionReq); ++ REQUEST_SIZE_MATCH(xDRI3QueryVersionReq); + + swaps(&stuff->length); + swapl(&stuff->majorVersion); +@@ -322,6 +323,7 @@ static int + sproc_dri3_open(ClientPtr client) + { + REQUEST(xDRI3OpenReq); ++ REQUEST_SIZE_MATCH(xDRI3OpenReq); + + swaps(&stuff->length); + swapl(&stuff->drawable); +@@ -333,6 +335,7 @@ static int + sproc_dri3_pixmap_from_buffer(ClientPtr client) + { + REQUEST(xDRI3PixmapFromBufferReq); ++ REQUEST_SIZE_MATCH(xDRI3PixmapFromBufferReq); + + swaps(&stuff->length); + swapl(&stuff->pixmap); +@@ -348,6 +351,7 @@ static int + sproc_dri3_buffer_from_pixmap(ClientPtr client) + { + REQUEST(xDRI3BufferFromPixmapReq); ++ REQUEST_SIZE_MATCH(xDRI3BufferFromPixmapReq); + + swaps(&stuff->length); + swapl(&stuff->pixmap); +@@ -358,6 +362,7 @@ static int + sproc_dri3_fence_from_fd(ClientPtr client) + { + REQUEST(xDRI3FenceFromFDReq); ++ REQUEST_SIZE_MATCH(xDRI3FenceFromFDReq); + + swaps(&stuff->length); + swapl(&stuff->drawable); +@@ -369,6 +374,7 @@ static int + sproc_dri3_fd_from_fence(ClientPtr client) + { + REQUEST(xDRI3FDFromFenceReq); ++ REQUEST_SIZE_MATCH(xDRI3FDFromFenceReq); + + swaps(&stuff->length); + swapl(&stuff->drawable); +-- +1.9.3 + diff --git a/SOURCES/0012-present-unvalidated-lengths-in-Present-extension-pro.patch b/SOURCES/0012-present-unvalidated-lengths-in-Present-extension-pro.patch new file mode 100644 index 0000000..54575b6 --- /dev/null +++ b/SOURCES/0012-present-unvalidated-lengths-in-Present-extension-pro.patch @@ -0,0 +1,69 @@ +From a2ae01b5777b94b1e7bf7319223365f57c213a57 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 26 Jan 2014 19:33:34 -0800 +Subject: [PATCH 12/33] present: unvalidated lengths in Present extension procs + [CVE-2014-8103 2/2] + +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +Reviewed-by: Julien Cristau +Signed-off-by: Fedora X Ninjas +--- + present/present_request.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/present/present_request.c b/present/present_request.c +index 1064dcb..1a60c8a 100644 +--- a/present/present_request.c ++++ b/present/present_request.c +@@ -210,6 +210,7 @@ proc_present_query_capabilities (ClientPtr client) + RRCrtcPtr crtc = NULL; + int r; + ++ REQUEST_SIZE_MATCH(xPresentQueryCapabilitiesReq); + r = dixLookupWindow(&window, stuff->target, client, DixGetAttrAccess); + switch (r) { + case Success: +@@ -254,6 +255,7 @@ static int + sproc_present_query_version(ClientPtr client) + { + REQUEST(xPresentQueryVersionReq); ++ REQUEST_SIZE_MATCH(xPresentQueryVersionReq); + + swaps(&stuff->length); + swapl(&stuff->majorVersion); +@@ -265,6 +267,7 @@ static int + sproc_present_pixmap(ClientPtr client) + { + REQUEST(xPresentPixmapReq); ++ REQUEST_AT_LEAST_SIZE(xPresentPixmapReq); + + swaps(&stuff->length); + swapl(&stuff->window); +@@ -284,6 +287,7 @@ static int + sproc_present_notify_msc(ClientPtr client) + { + REQUEST(xPresentNotifyMSCReq); ++ REQUEST_SIZE_MATCH(xPresentNotifyMSCReq); + + swaps(&stuff->length); + swapl(&stuff->window); +@@ -297,6 +301,7 @@ static int + sproc_present_select_input (ClientPtr client) + { + REQUEST(xPresentSelectInputReq); ++ REQUEST_SIZE_MATCH(xPresentSelectInputReq); + + swaps(&stuff->length); + swapl(&stuff->window); +@@ -308,6 +313,7 @@ static int + sproc_present_query_capabilities (ClientPtr client) + { + REQUEST(xPresentQueryCapabilitiesReq); ++ REQUEST_SIZE_MATCH(xPresentQueryCapabilitiesReq); + swaps(&stuff->length); + swapl(&stuff->target); + return (*proc_present_vector[stuff->presentReqType]) (client); +-- +1.9.3 + diff --git a/SOURCES/0013-randr-unvalidated-lengths-in-RandR-extension-swapped.patch b/SOURCES/0013-randr-unvalidated-lengths-in-RandR-extension-swapped.patch new file mode 100644 index 0000000..dec7cb0 --- /dev/null +++ b/SOURCES/0013-randr-unvalidated-lengths-in-RandR-extension-swapped.patch @@ -0,0 +1,52 @@ +From 7b32b2e84bdd72ab9e304645b714f06d1732f490 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 26 Jan 2014 19:38:09 -0800 +Subject: [PATCH 13/33] randr: unvalidated lengths in RandR extension swapped + procs [CVE-2014-8101] + +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +Signed-off-by: Fedora X Ninjas +--- + randr/rrsdispatch.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/randr/rrsdispatch.c b/randr/rrsdispatch.c +index 9968c7f..5af8fec 100644 +--- a/randr/rrsdispatch.c ++++ b/randr/rrsdispatch.c +@@ -27,6 +27,7 @@ SProcRRQueryVersion(ClientPtr client) + { + REQUEST(xRRQueryVersionReq); + ++ REQUEST_SIZE_MATCH(xRRQueryVersionReq); + swaps(&stuff->length); + swapl(&stuff->majorVersion); + swapl(&stuff->minorVersion); +@@ -38,6 +39,7 @@ SProcRRGetScreenInfo(ClientPtr client) + { + REQUEST(xRRGetScreenInfoReq); + ++ REQUEST_SIZE_MATCH(xRRGetScreenInfoReq); + swaps(&stuff->length); + swapl(&stuff->window); + return (*ProcRandrVector[stuff->randrReqType]) (client); +@@ -69,6 +71,7 @@ SProcRRSelectInput(ClientPtr client) + { + REQUEST(xRRSelectInputReq); + ++ REQUEST_SIZE_MATCH(xRRSelectInputReq); + swaps(&stuff->length); + swapl(&stuff->window); + swaps(&stuff->enable); +@@ -152,6 +155,7 @@ SProcRRConfigureOutputProperty(ClientPtr client) + { + REQUEST(xRRConfigureOutputPropertyReq); + ++ REQUEST_AT_LEAST_SIZE(xRRConfigureOutputPropertyReq); + swaps(&stuff->length); + swapl(&stuff->output); + swapl(&stuff->property); +-- +1.9.3 + diff --git a/SOURCES/0014-render-check-request-size-before-reading-it-CVE-2014.patch b/SOURCES/0014-render-check-request-size-before-reading-it-CVE-2014.patch new file mode 100644 index 0000000..09fc6a0 --- /dev/null +++ b/SOURCES/0014-render-check-request-size-before-reading-it-CVE-2014.patch @@ -0,0 +1,37 @@ +From 4b0137857115c025232c866d0ecd3a68688ca9e4 Mon Sep 17 00:00:00 2001 +From: Julien Cristau +Date: Tue, 28 Oct 2014 10:30:04 +0100 +Subject: [PATCH 14/33] render: check request size before reading it + [CVE-2014-8100 1/2] + +Otherwise we may be reading outside of the client request. + +Signed-off-by: Julien Cristau +Reviewed-by: Alan Coopersmith +Signed-off-by: Alan Coopersmith +Signed-off-by: Fedora X Ninjas +--- + render/render.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/render/render.c b/render/render.c +index 51f75ae..ce03b13 100644 +--- a/render/render.c ++++ b/render/render.c +@@ -276,11 +276,11 @@ ProcRenderQueryVersion(ClientPtr client) + + REQUEST(xRenderQueryVersionReq); + ++ REQUEST_SIZE_MATCH(xRenderQueryVersionReq); ++ + pRenderClient->major_version = stuff->majorVersion; + pRenderClient->minor_version = stuff->minorVersion; + +- REQUEST_SIZE_MATCH(xRenderQueryVersionReq); +- + if ((stuff->majorVersion * 1000 + stuff->minorVersion) < + (SERVER_RENDER_MAJOR_VERSION * 1000 + SERVER_RENDER_MINOR_VERSION)) { + rep.majorVersion = stuff->majorVersion; +-- +1.9.3 + diff --git a/SOURCES/0015-render-unvalidated-lengths-in-Render-extn.-swapped-p.patch b/SOURCES/0015-render-unvalidated-lengths-in-Render-extn.-swapped-p.patch new file mode 100644 index 0000000..caaa3b3 --- /dev/null +++ b/SOURCES/0015-render-unvalidated-lengths-in-Render-extn.-swapped-p.patch @@ -0,0 +1,141 @@ +From eec950e6fcafd315b5f211c78fc7d4b775df1036 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 26 Jan 2014 19:51:29 -0800 +Subject: [PATCH 15/33] render: unvalidated lengths in Render extn. swapped + procs [CVE-2014-8100 2/2] + +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +Signed-off-by: Fedora X Ninjas +--- + render/render.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +diff --git a/render/render.c b/render/render.c +index ce03b13..4e47efd 100644 +--- a/render/render.c ++++ b/render/render.c +@@ -1995,7 +1995,7 @@ static int + SProcRenderQueryVersion(ClientPtr client) + { + REQUEST(xRenderQueryVersionReq); +- ++ REQUEST_SIZE_MATCH(xRenderQueryVersionReq); + swaps(&stuff->length); + swapl(&stuff->majorVersion); + swapl(&stuff->minorVersion); +@@ -2006,6 +2006,7 @@ static int + SProcRenderQueryPictFormats(ClientPtr client) + { + REQUEST(xRenderQueryPictFormatsReq); ++ REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq); + swaps(&stuff->length); + return (*ProcRenderVector[stuff->renderReqType]) (client); + } +@@ -2014,6 +2015,7 @@ static int + SProcRenderQueryPictIndexValues(ClientPtr client) + { + REQUEST(xRenderQueryPictIndexValuesReq); ++ REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq); + swaps(&stuff->length); + swapl(&stuff->format); + return (*ProcRenderVector[stuff->renderReqType]) (client); +@@ -2029,6 +2031,7 @@ static int + SProcRenderCreatePicture(ClientPtr client) + { + REQUEST(xRenderCreatePictureReq); ++ REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq); + swaps(&stuff->length); + swapl(&stuff->pid); + swapl(&stuff->drawable); +@@ -2042,6 +2045,7 @@ static int + SProcRenderChangePicture(ClientPtr client) + { + REQUEST(xRenderChangePictureReq); ++ REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq); + swaps(&stuff->length); + swapl(&stuff->picture); + swapl(&stuff->mask); +@@ -2053,6 +2057,7 @@ static int + SProcRenderSetPictureClipRectangles(ClientPtr client) + { + REQUEST(xRenderSetPictureClipRectanglesReq); ++ REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq); + swaps(&stuff->length); + swapl(&stuff->picture); + swaps(&stuff->xOrigin); +@@ -2065,6 +2070,7 @@ static int + SProcRenderFreePicture(ClientPtr client) + { + REQUEST(xRenderFreePictureReq); ++ REQUEST_SIZE_MATCH(xRenderFreePictureReq); + swaps(&stuff->length); + swapl(&stuff->picture); + return (*ProcRenderVector[stuff->renderReqType]) (client); +@@ -2074,6 +2080,7 @@ static int + SProcRenderComposite(ClientPtr client) + { + REQUEST(xRenderCompositeReq); ++ REQUEST_SIZE_MATCH(xRenderCompositeReq); + swaps(&stuff->length); + swapl(&stuff->src); + swapl(&stuff->mask); +@@ -2093,6 +2100,7 @@ static int + SProcRenderScale(ClientPtr client) + { + REQUEST(xRenderScaleReq); ++ REQUEST_SIZE_MATCH(xRenderScaleReq); + swaps(&stuff->length); + swapl(&stuff->src); + swapl(&stuff->dst); +@@ -2193,6 +2201,7 @@ static int + SProcRenderCreateGlyphSet(ClientPtr client) + { + REQUEST(xRenderCreateGlyphSetReq); ++ REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq); + swaps(&stuff->length); + swapl(&stuff->gsid); + swapl(&stuff->format); +@@ -2203,6 +2212,7 @@ static int + SProcRenderReferenceGlyphSet(ClientPtr client) + { + REQUEST(xRenderReferenceGlyphSetReq); ++ REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq); + swaps(&stuff->length); + swapl(&stuff->gsid); + swapl(&stuff->existing); +@@ -2213,6 +2223,7 @@ static int + SProcRenderFreeGlyphSet(ClientPtr client) + { + REQUEST(xRenderFreeGlyphSetReq); ++ REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq); + swaps(&stuff->length); + swapl(&stuff->glyphset); + return (*ProcRenderVector[stuff->renderReqType]) (client); +@@ -2227,6 +2238,7 @@ SProcRenderAddGlyphs(ClientPtr client) + xGlyphInfo *gi; + + REQUEST(xRenderAddGlyphsReq); ++ REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq); + swaps(&stuff->length); + swapl(&stuff->glyphset); + swapl(&stuff->nglyphs); +@@ -2261,6 +2273,7 @@ static int + SProcRenderFreeGlyphs(ClientPtr client) + { + REQUEST(xRenderFreeGlyphsReq); ++ REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq); + swaps(&stuff->length); + swapl(&stuff->glyphset); + SwapRestL(stuff); +@@ -2278,6 +2291,7 @@ SProcRenderCompositeGlyphs(ClientPtr client) + int size; + + REQUEST(xRenderCompositeGlyphsReq); ++ REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq); + + switch (stuff->renderReqType) { + default: +-- +1.9.3 + diff --git a/SOURCES/0016-xfixes-unvalidated-length-in-SProcXFixesSelectSelect.patch b/SOURCES/0016-xfixes-unvalidated-length-in-SProcXFixesSelectSelect.patch new file mode 100644 index 0000000..963fd44 --- /dev/null +++ b/SOURCES/0016-xfixes-unvalidated-length-in-SProcXFixesSelectSelect.patch @@ -0,0 +1,28 @@ +From 9994f0703ab49802e956f0ccae1ddb50143b6bad Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 26 Jan 2014 20:02:20 -0800 +Subject: [PATCH 16/33] xfixes: unvalidated length in + SProcXFixesSelectSelectionInput [CVE-2014-8102] + +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +Signed-off-by: Fedora X Ninjas +--- + xfixes/select.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/xfixes/select.c b/xfixes/select.c +index ee8ed6f..c5a68ca 100644 +--- a/xfixes/select.c ++++ b/xfixes/select.c +@@ -201,6 +201,7 @@ SProcXFixesSelectSelectionInput(ClientPtr client) + { + REQUEST(xXFixesSelectSelectionInputReq); + ++ REQUEST_SIZE_MATCH(xXFixesSelectSelectionInputReq); + swaps(&stuff->length); + swapl(&stuff->window); + swapl(&stuff->selection); +-- +1.9.3 + diff --git a/SOURCES/0017-Add-request-length-checking-test-cases-for-some-Xinp.patch b/SOURCES/0017-Add-request-length-checking-test-cases-for-some-Xinp.patch new file mode 100644 index 0000000..7700c78 --- /dev/null +++ b/SOURCES/0017-Add-request-length-checking-test-cases-for-some-Xinp.patch @@ -0,0 +1,214 @@ +From 2bc68568ee6d8b75da07d98818142af081f0b132 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 9 Feb 2014 21:27:27 -0800 +Subject: [PATCH 17/33] Add request length checking test cases for some Xinput + 1.x requests + +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +Signed-off-by: Fedora X Ninjas +--- + configure.ac | 1 + + test/Makefile.am | 2 +- + test/xi1/Makefile.am | 34 +++++++++ + test/xi1/protocol-xchangedevicecontrol.c | 122 +++++++++++++++++++++++++++++++ + 4 files changed, 158 insertions(+), 1 deletion(-) + create mode 100644 test/xi1/Makefile.am + create mode 100644 test/xi1/protocol-xchangedevicecontrol.c + +diff --git a/configure.ac b/configure.ac +index 2202a56..e1f0fe4 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2538,6 +2538,7 @@ hw/kdrive/fbdev/Makefile + hw/kdrive/linux/Makefile + hw/kdrive/src/Makefile + test/Makefile ++test/xi1/Makefile + test/xi2/Makefile + xserver.ent + xorg-server.pc +diff --git a/test/Makefile.am b/test/Makefile.am +index 2852bb3..cd739e2 100644 +--- a/test/Makefile.am ++++ b/test/Makefile.am +@@ -4,7 +4,7 @@ noinst_PROGRAMS = list string + if XORG + # Tests that require at least some DDX functions in order to fully link + # For now, requires xf86 ddx, could be adjusted to use another +-SUBDIRS += xi2 ++SUBDIRS += xi1 xi2 + noinst_PROGRAMS += xkb input xtest misc fixes xfree86 hashtabletest os signal-logging touch + endif + check_LTLIBRARIES = libxservertest.la +diff --git a/test/xi1/Makefile.am b/test/xi1/Makefile.am +new file mode 100644 +index 0000000..907fa7a +--- /dev/null ++++ b/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/test/xi1/protocol-xchangedevicecontrol.c b/test/xi1/protocol-xchangedevicecontrol.c +new file mode 100644 +index 0000000..8e638b2 +--- /dev/null ++++ b/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; ++} +-- +1.9.3 + diff --git a/SOURCES/0018-Add-request-length-checking-test-cases-for-some-Xinp.patch b/SOURCES/0018-Add-request-length-checking-test-cases-for-some-Xinp.patch new file mode 100644 index 0000000..ad128a0 --- /dev/null +++ b/SOURCES/0018-Add-request-length-checking-test-cases-for-some-Xinp.patch @@ -0,0 +1,90 @@ +From 2c23ed603e792f8bf958ec8056e5e13c35a4c0fe Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 9 Feb 2014 21:28:05 -0800 +Subject: [PATCH 18/33] Add request length checking test cases for some Xinput + 2.x requests + +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +Signed-off-by: Fedora X Ninjas +--- + test/xi2/protocol-xigetclientpointer.c | 5 +++++ + test/xi2/protocol-xipassivegrabdevice.c | 8 ++++++++ + test/xi2/protocol-xiquerypointer.c | 4 ++++ + test/xi2/protocol-xiwarppointer.c | 3 +++ + 4 files changed, 20 insertions(+) + +diff --git a/test/xi2/protocol-xigetclientpointer.c b/test/xi2/protocol-xigetclientpointer.c +index 28eb8d3..570c53e 100644 +--- a/test/xi2/protocol-xigetclientpointer.c ++++ b/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/test/xi2/protocol-xipassivegrabdevice.c b/test/xi2/protocol-xipassivegrabdevice.c +index 84b386b..d0b9004 100644 +--- a/test/xi2/protocol-xipassivegrabdevice.c ++++ b/test/xi2/protocol-xipassivegrabdevice.c +@@ -138,6 +138,7 @@ request_XIPassiveGrabDevice(ClientPtr client, xXIPassiveGrabDeviceReq * req, + int rc; + int modifiers; + ++ client_request.req_len = req->length; + rc = ProcXIPassiveGrabDevice(&client_request); + assert(rc == error); + +@@ -188,6 +189,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/test/xi2/protocol-xiquerypointer.c b/test/xi2/protocol-xiquerypointer.c +index fc66b64..c0421f6 100644 +--- a/test/xi2/protocol-xiquerypointer.c ++++ b/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/test/xi2/protocol-xiwarppointer.c b/test/xi2/protocol-xiwarppointer.c +index f7986c1..3aaaae6 100644 +--- a/test/xi2/protocol-xiwarppointer.c ++++ b/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 +-- +1.9.3 + diff --git a/SOURCES/0019-Add-REQUEST_FIXED_SIZE-testcases-to-test-misc.c.patch b/SOURCES/0019-Add-REQUEST_FIXED_SIZE-testcases-to-test-misc.c.patch new file mode 100644 index 0000000..37403c3 --- /dev/null +++ b/SOURCES/0019-Add-REQUEST_FIXED_SIZE-testcases-to-test-misc.c.patch @@ -0,0 +1,75 @@ +From 19434b3ce4ed730d71155ba3edf44f68979ddb28 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 9 Feb 2014 22:42:47 -0800 +Subject: [PATCH 19/33] Add REQUEST_FIXED_SIZE testcases to test/misc.c + +Signed-off-by: Alan Coopersmith +Reviewed-by: Peter Hutterer +Signed-off-by: Fedora X Ninjas +--- + test/misc.c | 37 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 37 insertions(+) + +diff --git a/test/misc.c b/test/misc.c +index dd792e6..66330a1 100644 +--- a/test/misc.c ++++ b/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; + } +-- +1.9.3 + diff --git a/SOURCES/0020-glx-Be-more-paranoid-about-variable-length-requests-.patch b/SOURCES/0020-glx-Be-more-paranoid-about-variable-length-requests-.patch new file mode 100644 index 0000000..d700194 --- /dev/null +++ b/SOURCES/0020-glx-Be-more-paranoid-about-variable-length-requests-.patch @@ -0,0 +1,48 @@ +From 326a95955f6dd3c157ba7ddf41a4b11304764c53 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:36 -0500 +Subject: [PATCH 20/33] glx: Be more paranoid about variable-length requests + [CVE-2014-8093 1/6] + +If the size computation routine returns -1 we should just reject the +request outright. Clamping it to zero could give an attacker the +opportunity to also mangle cmdlen in such a way that the subsequent +length check passes, and the request would get executed, thus passing +data we wanted to reject to the renderer. + +Reviewed-by: Keith Packard +Reviewed-by: Julien Cristau +Reviewed-by: Michal Srb +Reviewed-by: Andy Ritger +Signed-off-by: Adam Jackson +Signed-off-by: Alan Coopersmith +Signed-off-by: Fedora X Ninjas +--- + glx/glxcmds.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/glx/glxcmds.c b/glx/glxcmds.c +index b8da048..27777e9 100644 +--- a/glx/glxcmds.c ++++ b/glx/glxcmds.c +@@ -2052,7 +2052,7 @@ __glXDisp_Render(__GLXclientState * cl, GLbyte * pc) + extra = (*entry.varsize) (pc + __GLX_RENDER_HDR_SIZE, + client->swapped); + if (extra < 0) { +- extra = 0; ++ return BadLength; + } + if (cmdlen != __GLX_PAD(entry.bytes + extra)) { + return BadLength; +@@ -2169,7 +2169,7 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc) + extra = (*entry.varsize) (pc + __GLX_RENDER_LARGE_HDR_SIZE, + client->swapped); + if (extra < 0) { +- extra = 0; ++ return BadLength; + } + /* large command's header is 4 bytes longer, so add 4 */ + if (cmdlen != __GLX_PAD(entry.bytes + 4 + extra)) { +-- +1.9.3 + diff --git a/SOURCES/0021-glx-Be-more-strict-about-rejecting-invalid-image-siz.patch b/SOURCES/0021-glx-Be-more-strict-about-rejecting-invalid-image-siz.patch new file mode 100644 index 0000000..5af9a12 --- /dev/null +++ b/SOURCES/0021-glx-Be-more-strict-about-rejecting-invalid-image-siz.patch @@ -0,0 +1,166 @@ +From 679072061a39f72d4473b3a9c45f4bef6383f033 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:37 -0500 +Subject: [PATCH 21/33] glx: Be more strict about rejecting invalid image sizes + [CVE-2014-8093 2/6] + +Before this we'd just clamp the image size to 0, which was just +hideously stupid; if the parameters were such that they'd overflow an +integer, you'd allocate a small buffer, then pass huge values into (say) +ReadPixels, and now you're scribbling over arbitrary server memory. + +Reviewed-by: Keith Packard +Reviewed-by: Julien Cristau +Reviewed-by: Michal Srb +Reviewed-by: Andy Ritger +Signed-off-by: Adam Jackson +Signed-off-by: Alan Coopersmith +Signed-off-by: Fedora X Ninjas +--- + glx/singlepix.c | 16 ++++++++-------- + glx/singlepixswap.c | 16 ++++++++-------- + 2 files changed, 16 insertions(+), 16 deletions(-) + +diff --git a/glx/singlepix.c b/glx/singlepix.c +index 506fdaa..8b6c261 100644 +--- a/glx/singlepix.c ++++ b/glx/singlepix.c +@@ -65,7 +65,7 @@ __glXDisp_ReadPixels(__GLXclientState * cl, GLbyte * pc) + lsbFirst = *(GLboolean *) (pc + 25); + compsize = __glReadPixels_size(format, type, width, height); + if (compsize < 0) +- compsize = 0; ++ return BadLength; + + glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes); + glPixelStorei(GL_PACK_LSB_FIRST, lsbFirst); +@@ -124,7 +124,7 @@ __glXDisp_GetTexImage(__GLXclientState * cl, GLbyte * pc) + compsize = + __glGetTexImage_size(target, level, format, type, width, height, depth); + if (compsize < 0) +- compsize = 0; ++ return BadLength; + + glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +@@ -218,9 +218,9 @@ GetSeparableFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) + compsize2 = __glGetTexImage_size(target, 1, format, type, height, 1, 1); + + if (compsize < 0) +- compsize = 0; ++ return BadLength; + if (compsize2 < 0) +- compsize2 = 0; ++ return BadLength; + compsize = __GLX_PAD(compsize); + compsize2 = __GLX_PAD(compsize2); + +@@ -296,7 +296,7 @@ GetConvolutionFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) + */ + compsize = __glGetTexImage_size(target, 1, format, type, width, height, 1); + if (compsize < 0) +- compsize = 0; ++ return BadLength; + + glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +@@ -365,7 +365,7 @@ GetHistogram(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) + */ + compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1); + if (compsize < 0) +- compsize = 0; ++ return BadLength; + + glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +@@ -426,7 +426,7 @@ GetMinmax(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) + + compsize = __glGetTexImage_size(target, 1, format, type, 2, 1, 1); + if (compsize < 0) +- compsize = 0; ++ return BadLength; + + glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +@@ -491,7 +491,7 @@ GetColorTable(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) + */ + compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1); + if (compsize < 0) +- compsize = 0; ++ return BadLength; + + glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +diff --git a/glx/singlepixswap.c b/glx/singlepixswap.c +index 8469101..8dc304f 100644 +--- a/glx/singlepixswap.c ++++ b/glx/singlepixswap.c +@@ -75,7 +75,7 @@ __glXDispSwap_ReadPixels(__GLXclientState * cl, GLbyte * pc) + lsbFirst = *(GLboolean *) (pc + 25); + compsize = __glReadPixels_size(format, type, width, height); + if (compsize < 0) +- compsize = 0; ++ return BadLength; + + glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes); + glPixelStorei(GL_PACK_LSB_FIRST, lsbFirst); +@@ -144,7 +144,7 @@ __glXDispSwap_GetTexImage(__GLXclientState * cl, GLbyte * pc) + compsize = + __glGetTexImage_size(target, level, format, type, width, height, depth); + if (compsize < 0) +- compsize = 0; ++ return BadLength; + + glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +@@ -252,9 +252,9 @@ GetSeparableFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) + compsize2 = __glGetTexImage_size(target, 1, format, type, height, 1, 1); + + if (compsize < 0) +- compsize = 0; ++ return BadLength; + if (compsize2 < 0) +- compsize2 = 0; ++ return BadLength; + compsize = __GLX_PAD(compsize); + compsize2 = __GLX_PAD(compsize2); + +@@ -338,7 +338,7 @@ GetConvolutionFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) + */ + compsize = __glGetTexImage_size(target, 1, format, type, width, height, 1); + if (compsize < 0) +- compsize = 0; ++ return BadLength; + + glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +@@ -415,7 +415,7 @@ GetHistogram(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) + */ + compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1); + if (compsize < 0) +- compsize = 0; ++ return BadLength; + + glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +@@ -483,7 +483,7 @@ GetMinmax(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) + + compsize = __glGetTexImage_size(target, 1, format, type, 2, 1, 1); + if (compsize < 0) +- compsize = 0; ++ return BadLength; + + glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +@@ -554,7 +554,7 @@ GetColorTable(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) + */ + compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1); + if (compsize < 0) +- compsize = 0; ++ return BadLength; + + glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +-- +1.9.3 + diff --git a/SOURCES/0022-glx-Additional-paranoia-in-__glXGetAnswerBuffer-__GL.patch b/SOURCES/0022-glx-Additional-paranoia-in-__glXGetAnswerBuffer-__GL.patch new file mode 100644 index 0000000..98d12cd --- /dev/null +++ b/SOURCES/0022-glx-Additional-paranoia-in-__glXGetAnswerBuffer-__GL.patch @@ -0,0 +1,60 @@ +From 4c909ffb1b8d6fc2ba61dc764e047f95dd8950b7 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:38 -0500 +Subject: [PATCH 22/33] glx: Additional paranoia in __glXGetAnswerBuffer / + __GLX_GET_ANSWER_BUFFER (v2) [CVE-2014-8093 3/6] + +If the computed reply size is negative, something went wrong, treat it +as an error. + +v2: Be more careful about size_t being unsigned (Matthieu Herrb) +v3: SIZE_MAX not SIZE_T_MAX (Alan Coopersmith) + +Reviewed-by: Julien Cristau +Reviewed-by: Michal Srb +Reviewed-by: Andy Ritger +Signed-off-by: Adam Jackson +Signed-off-by: Alan Coopersmith +Signed-off-by: Fedora X Ninjas +--- + glx/indirect_util.c | 7 ++++++- + glx/unpack.h | 3 ++- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/glx/indirect_util.c b/glx/indirect_util.c +index f9d1243..183af83 100644 +--- a/glx/indirect_util.c ++++ b/glx/indirect_util.c +@@ -76,9 +76,14 @@ __glXGetAnswerBuffer(__GLXclientState * cl, size_t required_size, + const unsigned mask = alignment - 1; + + if (local_size < required_size) { +- const size_t worst_case_size = required_size + alignment; ++ size_t worst_case_size; + intptr_t temp_buf; + ++ if (required_size < SIZE_MAX - alignment) ++ worst_case_size = required_size + alignment; ++ else ++ return NULL; ++ + if (cl->returnBufSize < worst_case_size) { + void *temp = realloc(cl->returnBuf, worst_case_size); + +diff --git a/glx/unpack.h b/glx/unpack.h +index 52fba74..2b1ebcf 100644 +--- a/glx/unpack.h ++++ b/glx/unpack.h +@@ -83,7 +83,8 @@ extern xGLXSingleReply __glXReply; + ** pointer. + */ + #define __GLX_GET_ANSWER_BUFFER(res,cl,size,align) \ +- if ((size) > sizeof(answerBuffer)) { \ ++ if (size < 0) return BadLength; \ ++ else if ((size) > sizeof(answerBuffer)) { \ + int bump; \ + if ((cl)->returnBufSize < (size)+(align)) { \ + (cl)->returnBuf = (GLbyte*)realloc((cl)->returnBuf, \ +-- +1.9.3 + diff --git a/SOURCES/0023-glx-Fix-image-size-computation-for-EXT_texture_integ.patch b/SOURCES/0023-glx-Fix-image-size-computation-for-EXT_texture_integ.patch new file mode 100644 index 0000000..6e97c00 --- /dev/null +++ b/SOURCES/0023-glx-Fix-image-size-computation-for-EXT_texture_integ.patch @@ -0,0 +1,60 @@ +From 4941859d354bb0cc02dbc2589a43e29e13dfeba6 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:39 -0500 +Subject: [PATCH 23/33] glx: Fix image size computation for EXT_texture_integer + [CVE-2014-8098 1/8] + +Without this we'd reject the request with BadLength. Note that some old +versions of Mesa had a bug in the same place, and would _send_ zero +bytes of image data; these will now be rejected, correctly. + +Reviewed-by: Keith Packard +Reviewed-by: Julien Cristau +Reviewed-by: Michal Srb +Reviewed-by: Andy Ritger +Signed-off-by: Adam Jackson +Signed-off-by: Alan Coopersmith +Signed-off-by: Fedora X Ninjas +--- + glx/rensize.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/glx/rensize.c b/glx/rensize.c +index bcc3a53..10f76bc 100644 +--- a/glx/rensize.c ++++ b/glx/rensize.c +@@ -224,6 +224,11 @@ __glXImageSize(GLenum format, GLenum type, GLenum target, + case GL_ALPHA: + case GL_LUMINANCE: + case GL_INTENSITY: ++ case GL_RED_INTEGER_EXT: ++ case GL_GREEN_INTEGER_EXT: ++ case GL_BLUE_INTEGER_EXT: ++ case GL_ALPHA_INTEGER_EXT: ++ case GL_LUMINANCE_INTEGER_EXT: + elementsPerGroup = 1; + break; + case GL_422_EXT: +@@ -234,14 +239,19 @@ __glXImageSize(GLenum format, GLenum type, GLenum target, + case GL_DEPTH_STENCIL_MESA: + case GL_YCBCR_MESA: + case GL_LUMINANCE_ALPHA: ++ case GL_LUMINANCE_ALPHA_INTEGER_EXT: + elementsPerGroup = 2; + break; + case GL_RGB: + case GL_BGR: ++ case GL_RGB_INTEGER_EXT: ++ case GL_BGR_INTEGER_EXT: + elementsPerGroup = 3; + break; + case GL_RGBA: + case GL_BGRA: ++ case GL_RGBA_INTEGER_EXT: ++ case GL_BGRA_INTEGER_EXT: + case GL_ABGR_EXT: + elementsPerGroup = 4; + break; +-- +1.9.3 + diff --git a/SOURCES/0024-glx-Add-safe_-add-mul-pad-v3-CVE-2014-8093-4-6.patch b/SOURCES/0024-glx-Add-safe_-add-mul-pad-v3-CVE-2014-8093-4-6.patch new file mode 100644 index 0000000..65962df --- /dev/null +++ b/SOURCES/0024-glx-Add-safe_-add-mul-pad-v3-CVE-2014-8093-4-6.patch @@ -0,0 +1,83 @@ +From f5a7c552b4e0268df93cce2d7f418a7f81770873 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:40 -0500 +Subject: [PATCH 24/33] glx: Add safe_{add,mul,pad} (v3) [CVE-2014-8093 4/6] + +These are paranoid about integer overflow, and will return -1 if their +operation would overflow a (signed) integer or if either argument is +negative. + +Note that RenderLarge requests are sized with a uint32_t so in principle +this could be sketchy there, but dix limits bigreqs to 128M so you +shouldn't ever notice, and honestly if you're sending more than 2G of +rendering commands you're already doing something very wrong. + +v2: Use INT_MAX for consistency with the rest of the server (jcristau) +v3: Reject negative arguments (anholt) + +Reviewed-by: Keith Packard +Reviewed-by: Julien Cristau +Reviewed-by: Michal Srb +Reviewed-by: Andy Ritger +Signed-off-by: Adam Jackson +Signed-off-by: Alan Coopersmith +Signed-off-by: Fedora X Ninjas +--- + glx/glxserver.h | 41 +++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 41 insertions(+) + +diff --git a/glx/glxserver.h b/glx/glxserver.h +index 7f36e5f..14c5dda 100644 +--- a/glx/glxserver.h ++++ b/glx/glxserver.h +@@ -230,6 +230,47 @@ extern void glxSwapQueryServerStringReply(ClientPtr client, + * Routines for computing the size of variably-sized rendering commands. + */ + ++static _X_INLINE int ++safe_add(int a, int b) ++{ ++ if (a < 0 || b < 0) ++ return -1; ++ ++ if (INT_MAX - a < b) ++ return -1; ++ ++ return a + b; ++} ++ ++static _X_INLINE int ++safe_mul(int a, int b) ++{ ++ if (a < 0 || b < 0) ++ return -1; ++ ++ if (a == 0 || b == 0) ++ return 0; ++ ++ if (a > INT_MAX / b) ++ return -1; ++ ++ return a * b; ++} ++ ++static _X_INLINE int ++safe_pad(int a) ++{ ++ int ret; ++ ++ if (a < 0) ++ return -1; ++ ++ if ((ret = safe_add(a, 3)) < 0) ++ return -1; ++ ++ return ret & (GLuint)~3; ++} ++ + extern int __glXTypeSize(GLenum enm); + extern int __glXImageSize(GLenum format, GLenum type, + GLenum target, GLsizei w, GLsizei h, GLsizei d, +-- +1.9.3 + diff --git a/SOURCES/0025-glx-Length-checking-for-GLXRender-requests-v2-CVE-20.patch b/SOURCES/0025-glx-Length-checking-for-GLXRender-requests-v2-CVE-20.patch new file mode 100644 index 0000000..9be4a5c --- /dev/null +++ b/SOURCES/0025-glx-Length-checking-for-GLXRender-requests-v2-CVE-20.patch @@ -0,0 +1,76 @@ +From e2f9051eb4dee56023b3d1b81baa6137bce4b56b Mon Sep 17 00:00:00 2001 +From: Julien Cristau +Date: Mon, 10 Nov 2014 12:13:41 -0500 +Subject: [PATCH 25/33] glx: Length checking for GLXRender requests (v2) + [CVE-2014-8098 2/8] + +v2: +Remove can't-happen comparison for cmdlen < 0 (Michal Srb) + +Reviewed-by: Adam Jackson +Reviewed-by: Michal Srb +Reviewed-by: Andy Ritger +Signed-off-by: Julien Cristau +Signed-off-by: Alan Coopersmith +Signed-off-by: Fedora X Ninjas +--- + glx/glxcmds.c | 21 ++++++++++----------- + 1 file changed, 10 insertions(+), 11 deletions(-) + +diff --git a/glx/glxcmds.c b/glx/glxcmds.c +index 27777e9..5b37e37 100644 +--- a/glx/glxcmds.c ++++ b/glx/glxcmds.c +@@ -2015,7 +2015,7 @@ __glXDisp_Render(__GLXclientState * cl, GLbyte * pc) + left = (req->length << 2) - sz_xGLXRenderReq; + while (left > 0) { + __GLXrenderSizeData entry; +- int extra; ++ int extra = 0; + __GLXdispatchRenderProcPtr proc; + int err; + +@@ -2034,6 +2034,9 @@ __glXDisp_Render(__GLXclientState * cl, GLbyte * pc) + cmdlen = hdr->length; + opcode = hdr->opcode; + ++ if (left < cmdlen) ++ return BadLength; ++ + /* + ** Check for core opcodes and grab entry data. + */ +@@ -2047,6 +2050,10 @@ __glXDisp_Render(__GLXclientState * cl, GLbyte * pc) + return __glXError(GLXBadRenderRequest); + } + ++ if (cmdlen < entry.bytes) { ++ return BadLength; ++ } ++ + if (entry.varsize) { + /* variable size command */ + extra = (*entry.varsize) (pc + __GLX_RENDER_HDR_SIZE, +@@ -2054,17 +2061,9 @@ __glXDisp_Render(__GLXclientState * cl, GLbyte * pc) + if (extra < 0) { + return BadLength; + } +- if (cmdlen != __GLX_PAD(entry.bytes + extra)) { +- return BadLength; +- } + } +- else { +- /* constant size command */ +- if (cmdlen != __GLX_PAD(entry.bytes)) { +- return BadLength; +- } +- } +- if (left < cmdlen) { ++ ++ if (cmdlen != safe_pad(safe_add(entry.bytes, extra))) { + return BadLength; + } + +-- +1.9.3 + diff --git a/SOURCES/0026-glx-Integer-overflow-protection-for-non-generated-re.patch b/SOURCES/0026-glx-Integer-overflow-protection-for-non-generated-re.patch new file mode 100644 index 0000000..8bbbdbf --- /dev/null +++ b/SOURCES/0026-glx-Integer-overflow-protection-for-non-generated-re.patch @@ -0,0 +1,226 @@ +From 2b07b8876559e0ec7fe6ac79ea49d8cabab2703f Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:42 -0500 +Subject: [PATCH 26/33] glx: Integer overflow protection for non-generated + render requests (v3) [CVE-2014-8093 5/6] + +v2: +Fix constants in __glXMap2fReqSize (Michal Srb) +Validate w/h/d for proxy targets too (Keith Packard) + +v3: +Fix Map[12]Size to correctly reject order == 0 (Julien Cristau) + +Reviewed-by: Keith Packard +Reviewed-by: Michal Srb +Reviewed-by: Andy Ritger +Signed-off-by: Adam Jackson +Signed-off-by: Alan Coopersmith +Signed-off-by: Fedora X Ninjas +--- + glx/rensize.c | 77 +++++++++++++++++++++++++++++++---------------------------- + 1 file changed, 41 insertions(+), 36 deletions(-) + +diff --git a/glx/rensize.c b/glx/rensize.c +index 10f76bc..6ee0f9c 100644 +--- a/glx/rensize.c ++++ b/glx/rensize.c +@@ -43,19 +43,11 @@ + (((a & 0xff000000U)>>24) | ((a & 0xff0000U)>>8) | \ + ((a & 0xff00U)<<8) | ((a & 0xffU)<<24)) + +-static int +-Map1Size(GLint k, GLint order) +-{ +- if (order <= 0 || k < 0) +- return -1; +- return k * order; +-} +- + int + __glXMap1dReqSize(const GLbyte * pc, Bool swap) + { + GLenum target; +- GLint order, k; ++ GLint order; + + target = *(GLenum *) (pc + 16); + order = *(GLint *) (pc + 20); +@@ -63,15 +55,16 @@ __glXMap1dReqSize(const GLbyte * pc, Bool swap) + target = SWAPL(target); + order = SWAPL(order); + } +- k = __glMap1d_size(target); +- return 8 * Map1Size(k, order); ++ if (order < 1) ++ return -1; ++ return safe_mul(8, safe_mul(__glMap1d_size(target), order)); + } + + int + __glXMap1fReqSize(const GLbyte * pc, Bool swap) + { + GLenum target; +- GLint order, k; ++ GLint order; + + target = *(GLenum *) (pc + 0); + order = *(GLint *) (pc + 12); +@@ -79,23 +72,24 @@ __glXMap1fReqSize(const GLbyte * pc, Bool swap) + target = SWAPL(target); + order = SWAPL(order); + } +- k = __glMap1f_size(target); +- return 4 * Map1Size(k, order); ++ if (order < 1) ++ return -1; ++ return safe_mul(4, safe_mul(__glMap1f_size(target), order)); + } + + static int + Map2Size(int k, int majorOrder, int minorOrder) + { +- if (majorOrder <= 0 || minorOrder <= 0 || k < 0) ++ if (majorOrder < 1 || minorOrder < 1) + return -1; +- return k * majorOrder * minorOrder; ++ return safe_mul(k, safe_mul(majorOrder, minorOrder)); + } + + int + __glXMap2dReqSize(const GLbyte * pc, Bool swap) + { + GLenum target; +- GLint uorder, vorder, k; ++ GLint uorder, vorder; + + target = *(GLenum *) (pc + 32); + uorder = *(GLint *) (pc + 36); +@@ -105,15 +99,14 @@ __glXMap2dReqSize(const GLbyte * pc, Bool swap) + uorder = SWAPL(uorder); + vorder = SWAPL(vorder); + } +- k = __glMap2d_size(target); +- return 8 * Map2Size(k, uorder, vorder); ++ return safe_mul(8, Map2Size(__glMap2d_size(target), uorder, vorder)); + } + + int + __glXMap2fReqSize(const GLbyte * pc, Bool swap) + { + GLenum target; +- GLint uorder, vorder, k; ++ GLint uorder, vorder; + + target = *(GLenum *) (pc + 0); + uorder = *(GLint *) (pc + 12); +@@ -123,8 +116,7 @@ __glXMap2fReqSize(const GLbyte * pc, Bool swap) + uorder = SWAPL(uorder); + vorder = SWAPL(vorder); + } +- k = __glMap2f_size(target); +- return 4 * Map2Size(k, uorder, vorder); ++ return safe_mul(4, Map2Size(__glMap2f_size(target), uorder, vorder)); + } + + /** +@@ -175,14 +167,16 @@ __glXImageSize(GLenum format, GLenum type, GLenum target, + GLint bytesPerElement, elementsPerGroup, groupsPerRow; + GLint groupSize, rowSize, padding, imageSize; + ++ if (w == 0 || h == 0 || d == 0) ++ return 0; ++ + if (w < 0 || h < 0 || d < 0 || + (type == GL_BITMAP && + (format != GL_COLOR_INDEX && format != GL_STENCIL_INDEX))) { + return -1; + } +- if (w == 0 || h == 0 || d == 0) +- return 0; + ++ /* proxy targets have no data */ + switch (target) { + case GL_PROXY_TEXTURE_1D: + case GL_PROXY_TEXTURE_2D: +@@ -199,6 +193,12 @@ __glXImageSize(GLenum format, GLenum type, GLenum target, + return 0; + } + ++ /* real data has to have real sizes */ ++ if (imageHeight < 0 || rowLength < 0 || skipImages < 0 || skipRows < 0) ++ return -1; ++ if (alignment != 1 && alignment != 2 && alignment != 4 && alignment != 8) ++ return -1; ++ + if (type == GL_BITMAP) { + if (rowLength > 0) { + groupsPerRow = rowLength; +@@ -207,11 +207,14 @@ __glXImageSize(GLenum format, GLenum type, GLenum target, + groupsPerRow = w; + } + rowSize = bits_to_bytes(groupsPerRow); ++ if (rowSize < 0) ++ return -1; + padding = (rowSize % alignment); + if (padding) { + rowSize += alignment - padding; + } +- return ((h + skipRows) * rowSize); ++ ++ return safe_mul(safe_add(h, skipRows), rowSize); + } + else { + switch (format) { +@@ -303,6 +306,7 @@ __glXImageSize(GLenum format, GLenum type, GLenum target, + default: + return -1; + } ++ /* known safe by the switches above, not checked */ + groupSize = bytesPerElement * elementsPerGroup; + if (rowLength > 0) { + groupsPerRow = rowLength; +@@ -310,18 +314,21 @@ __glXImageSize(GLenum format, GLenum type, GLenum target, + else { + groupsPerRow = w; + } +- rowSize = groupsPerRow * groupSize; ++ ++ if ((rowSize = safe_mul(groupsPerRow, groupSize)) < 0) ++ return -1; + padding = (rowSize % alignment); + if (padding) { + rowSize += alignment - padding; + } +- if (imageHeight > 0) { +- imageSize = (imageHeight + skipRows) * rowSize; +- } +- else { +- imageSize = (h + skipRows) * rowSize; +- } +- return ((d + skipImages) * imageSize); ++ ++ if (imageHeight > 0) ++ h = imageHeight; ++ h = safe_add(h, skipRows); ++ ++ imageSize = safe_mul(h, rowSize); ++ ++ return safe_mul(safe_add(d, skipImages), imageSize); + } + } + +@@ -445,9 +452,7 @@ __glXSeparableFilter2DReqSize(const GLbyte * pc, Bool swap) + /* XXX Should rowLength be used for either or both image? */ + image1size = __glXImageSize(format, type, 0, w, 1, 1, + 0, rowLength, 0, 0, alignment); +- image1size = __GLX_PAD(image1size); + image2size = __glXImageSize(format, type, 0, h, 1, 1, + 0, rowLength, 0, 0, alignment); +- return image1size + image2size; +- ++ return safe_add(safe_pad(image1size), image2size); + } +-- +1.9.3 + diff --git a/SOURCES/0027-glx-Top-level-length-checking-for-swapped-VendorPriv.patch b/SOURCES/0027-glx-Top-level-length-checking-for-swapped-VendorPriv.patch new file mode 100644 index 0000000..06456e5 --- /dev/null +++ b/SOURCES/0027-glx-Top-level-length-checking-for-swapped-VendorPriv.patch @@ -0,0 +1,52 @@ +From 4123cc39c0d1c801f3e41bb5c36dad904cbe5509 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:44 -0500 +Subject: [PATCH 27/33] glx: Top-level length checking for swapped + VendorPrivate requests [CVE-2014-8098 4/8] + +Reviewed-by: Keith Packard +Reviewed-by: Julien Cristau +Reviewed-by: Michal Srb +Reviewed-by: Andy Ritger +Signed-off-by: Adam Jackson +Signed-off-by: Alan Coopersmith +Signed-off-by: Fedora X Ninjas +--- + glx/glxcmdsswap.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/glx/glxcmdsswap.c b/glx/glxcmdsswap.c +index 5d179f3..9ec1222 100644 +--- a/glx/glxcmdsswap.c ++++ b/glx/glxcmdsswap.c +@@ -958,11 +958,13 @@ __glXDispSwap_RenderLarge(__GLXclientState * cl, GLbyte * pc) + int + __glXDispSwap_VendorPrivate(__GLXclientState * cl, GLbyte * pc) + { ++ ClientPtr client = cl->client; + xGLXVendorPrivateReq *req; + GLint vendorcode; + __GLXdispatchVendorPrivProcPtr proc; + + __GLX_DECLARE_SWAP_VARIABLES; ++ REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateReq); + + req = (xGLXVendorPrivateReq *) pc; + __GLX_SWAP_SHORT(&req->length); +@@ -985,11 +987,13 @@ __glXDispSwap_VendorPrivate(__GLXclientState * cl, GLbyte * pc) + int + __glXDispSwap_VendorPrivateWithReply(__GLXclientState * cl, GLbyte * pc) + { ++ ClientPtr client = cl->client; + xGLXVendorPrivateWithReplyReq *req; + GLint vendorcode; + __GLXdispatchVendorPrivProcPtr proc; + + __GLX_DECLARE_SWAP_VARIABLES; ++ REQUEST_AT_LEAST_SIZE(xGLXVendorPrivateWithReplyReq); + + req = (xGLXVendorPrivateWithReplyReq *) pc; + __GLX_SWAP_SHORT(&req->length); +-- +1.9.3 + diff --git a/SOURCES/0028-glx-Request-length-checks-for-SetClientInfoARB-CVE-2.patch b/SOURCES/0028-glx-Request-length-checks-for-SetClientInfoARB-CVE-2.patch new file mode 100644 index 0000000..2d2355b --- /dev/null +++ b/SOURCES/0028-glx-Request-length-checks-for-SetClientInfoARB-CVE-2.patch @@ -0,0 +1,75 @@ +From 4c8973a3f7632b82367c439b30c2b9444112c2ac Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:45 -0500 +Subject: [PATCH 28/33] glx: Request length checks for SetClientInfoARB + [CVE-2014-8098 5/8] + +Reviewed-by: Keith Packard +Reviewed-by: Julien Cristau +Reviewed-by: Michal Srb +Reviewed-by: Andy Ritger +Signed-off-by: Adam Jackson +Signed-off-by: Alan Coopersmith +Signed-off-by: Fedora X Ninjas +--- + glx/clientinfo.c | 19 ++++++++++++++----- + 1 file changed, 14 insertions(+), 5 deletions(-) + +diff --git a/glx/clientinfo.c b/glx/clientinfo.c +index 4aaa4c9..c5fef30 100644 +--- a/glx/clientinfo.c ++++ b/glx/clientinfo.c +@@ -33,18 +33,21 @@ static int + set_client_info(__GLXclientState * cl, xGLXSetClientInfoARBReq * req, + unsigned bytes_per_version) + { ++ ClientPtr client = cl->client; + char *gl_extensions; + char *glx_extensions; + ++ REQUEST_AT_LEAST_SIZE(xGLXSetClientInfoARBReq); ++ + /* Verify that the size of the packet matches the size inferred from the + * sizes specified for the various fields. + */ +- const unsigned expected_size = sz_xGLXSetClientInfoARBReq +- + (req->numVersions * bytes_per_version) +- + __GLX_PAD(req->numGLExtensionBytes) +- + __GLX_PAD(req->numGLXExtensionBytes); ++ int size = sz_xGLXSetClientInfoARBReq; ++ size = safe_add(size, safe_mul(req->numVersions, bytes_per_version)); ++ size = safe_add(size, safe_pad(req->numGLExtensionBytes)); ++ size = safe_add(size, safe_pad(req->numGLXExtensionBytes)); + +- if (req->length != (expected_size / 4)) ++ if (size < 0 || req->length != (size / 4)) + return BadLength; + + /* Verify that the actual length of the GL extension string matches what's +@@ -80,8 +83,11 @@ __glXDisp_SetClientInfoARB(__GLXclientState * cl, GLbyte * pc) + int + __glXDispSwap_SetClientInfoARB(__GLXclientState * cl, GLbyte * pc) + { ++ ClientPtr client = cl->client; + xGLXSetClientInfoARBReq *req = (xGLXSetClientInfoARBReq *) pc; + ++ REQUEST_AT_LEAST_SIZE(xGLXSetClientInfoARBReq); ++ + req->length = bswap_16(req->length); + req->numVersions = bswap_32(req->numVersions); + req->numGLExtensionBytes = bswap_32(req->numGLExtensionBytes); +@@ -99,8 +105,11 @@ __glXDisp_SetClientInfo2ARB(__GLXclientState * cl, GLbyte * pc) + int + __glXDispSwap_SetClientInfo2ARB(__GLXclientState * cl, GLbyte * pc) + { ++ ClientPtr client = cl->client; + xGLXSetClientInfoARBReq *req = (xGLXSetClientInfoARBReq *) pc; + ++ REQUEST_AT_LEAST_SIZE(xGLXSetClientInfoARBReq); ++ + req->length = bswap_16(req->length); + req->numVersions = bswap_32(req->numVersions); + req->numGLExtensionBytes = bswap_32(req->numGLExtensionBytes); +-- +1.9.3 + diff --git a/SOURCES/0029-glx-Length-checking-for-non-generated-vendor-private.patch b/SOURCES/0029-glx-Length-checking-for-non-generated-vendor-private.patch new file mode 100644 index 0000000..35ad31f --- /dev/null +++ b/SOURCES/0029-glx-Length-checking-for-non-generated-vendor-private.patch @@ -0,0 +1,46 @@ +From ba4578b09afdd9d7b232b442bba14520779a0a8d Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:46 -0500 +Subject: [PATCH 29/33] glx: Length-checking for non-generated vendor private + requests [CVE-2014-8098 6/8] + +Reviewed-by: Keith Packard +Reviewed-by: Michal Srb +Reviewed-by: Andy Ritger +Signed-off-by: Adam Jackson +Signed-off-by: Alan Coopersmith +Signed-off-by: Fedora X Ninjas +--- + glx/indirect_program.c | 2 ++ + glx/swap_interval.c | 2 ++ + 2 files changed, 4 insertions(+) + +diff --git a/glx/indirect_program.c b/glx/indirect_program.c +index fa4a240..965d7ed 100644 +--- a/glx/indirect_program.c ++++ b/glx/indirect_program.c +@@ -56,6 +56,8 @@ DoGetProgramString(struct __GLXclientStateRec *cl, GLbyte * pc, + __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); + ClientPtr client = cl->client; + ++ REQUEST_FIXED_SIZE(xGLXVendorPrivateWithReplyReq, 8); ++ + pc += __GLX_VENDPRIV_HDR_SIZE; + if (cx != NULL) { + GLenum target; +diff --git a/glx/swap_interval.c b/glx/swap_interval.c +index 17bc992..2320550 100644 +--- a/glx/swap_interval.c ++++ b/glx/swap_interval.c +@@ -46,6 +46,8 @@ DoSwapInterval(__GLXclientState * cl, GLbyte * pc, int do_swap) + __GLXcontext *cx; + GLint interval; + ++ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 4); ++ + cx = __glXLookupContextByTag(cl, tag); + + if ((cx == NULL) || (cx->pGlxScreen == NULL)) { +-- +1.9.3 + diff --git a/SOURCES/0030-glx-Length-checking-for-non-generated-single-request.patch b/SOURCES/0030-glx-Length-checking-for-non-generated-single-request.patch new file mode 100644 index 0000000..98c6b7d --- /dev/null +++ b/SOURCES/0030-glx-Length-checking-for-non-generated-single-request.patch @@ -0,0 +1,565 @@ +From 98fbd6f58553ba0d193a06d2b7b1820ea4483e67 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:47 -0500 +Subject: [PATCH 30/33] glx: Length checking for non-generated single requests + (v2) [CVE-2014-8098 7/8] + +v2: +Fix single versus vendor-private length checking for ARB_imaging subset +extensions. (Julien Cristau) + +v3: +Fix single versus vendor-private length checking for ARB_imaging subset +extensions. (Julien Cristau) + +Reviewed-by: Michal Srb +Reviewed-by: Andy Ritger +Signed-off-by: Adam Jackson +Signed-off-by: Julien Cristau +Signed-off-by: Alan Coopersmith +Signed-off-by: Fedora X Ninjas +--- + glx/indirect_texture_compression.c | 4 ++++ + glx/single2.c | 23 +++++++++++++++----- + glx/single2swap.c | 19 ++++++++++++---- + glx/singlepix.c | 44 +++++++++++++++++++++++++------------- + glx/singlepixswap.c | 34 ++++++++++++++++++++++++----- + 5 files changed, 95 insertions(+), 29 deletions(-) + +diff --git a/glx/indirect_texture_compression.c b/glx/indirect_texture_compression.c +index 94de47d..bb640ad 100644 +--- a/glx/indirect_texture_compression.c ++++ b/glx/indirect_texture_compression.c +@@ -43,6 +43,8 @@ __glXDisp_GetCompressedTexImage(struct __GLXclientStateRec *cl, GLbyte * pc) + __GLXcontext *const cx = __glXForceCurrent(cl, req->contextTag, &error); + ClientPtr client = cl->client; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 8); ++ + pc += __GLX_SINGLE_HDR_SIZE; + if (cx != NULL) { + const GLenum target = *(GLenum *) (pc + 0); +@@ -85,6 +87,8 @@ __glXDispSwap_GetCompressedTexImage(struct __GLXclientStateRec *cl, GLbyte * pc) + __glXForceCurrent(cl, bswap_32(req->contextTag), &error); + ClientPtr client = cl->client; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 8); ++ + pc += __GLX_SINGLE_HDR_SIZE; + if (cx != NULL) { + const GLenum target = (GLenum) bswap_32(*(int *) (pc + 0)); +diff --git a/glx/single2.c b/glx/single2.c +index 53b661d..a6ea614 100644 +--- a/glx/single2.c ++++ b/glx/single2.c +@@ -45,11 +45,14 @@ + int + __glXDisp_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc) + { ++ ClientPtr client = cl->client; + GLsizei size; + GLenum type; + __GLXcontext *cx; + int error; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 8); ++ + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { + return error; +@@ -76,10 +79,13 @@ __glXDisp_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc) + int + __glXDisp_SelectBuffer(__GLXclientState * cl, GLbyte * pc) + { ++ ClientPtr client = cl->client; + __GLXcontext *cx; + GLsizei size; + int error; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 4); ++ + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { + return error; +@@ -104,7 +110,7 @@ __glXDisp_SelectBuffer(__GLXclientState * cl, GLbyte * pc) + int + __glXDisp_RenderMode(__GLXclientState * cl, GLbyte * pc) + { +- ClientPtr client; ++ ClientPtr client = cl->client; + xGLXRenderModeReply reply; + __GLXcontext *cx; + GLint nitems = 0, retBytes = 0, retval, newModeCheck; +@@ -112,6 +118,8 @@ __glXDisp_RenderMode(__GLXclientState * cl, GLbyte * pc) + GLenum newMode; + int error; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 4); ++ + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { + return error; +@@ -188,7 +196,6 @@ __glXDisp_RenderMode(__GLXclientState * cl, GLbyte * pc) + ** selection array, as per the API for glRenderMode itself. + */ + noChangeAllowed:; +- client = cl->client; + reply = (xGLXRenderModeReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, +@@ -207,9 +214,12 @@ __glXDisp_RenderMode(__GLXclientState * cl, GLbyte * pc) + int + __glXDisp_Flush(__GLXclientState * cl, GLbyte * pc) + { ++ ClientPtr client = cl->client; + __GLXcontext *cx; + int error; + ++ REQUEST_SIZE_MATCH(xGLXSingleReq); ++ + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { + return error; +@@ -223,10 +233,12 @@ __glXDisp_Flush(__GLXclientState * cl, GLbyte * pc) + int + __glXDisp_Finish(__GLXclientState * cl, GLbyte * pc) + { ++ ClientPtr client = cl->client; + __GLXcontext *cx; +- ClientPtr client; + int error; + ++ REQUEST_SIZE_MATCH(xGLXSingleReq); ++ + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { + return error; +@@ -317,7 +329,7 @@ __glXcombine_strings(const char *cext_string, const char *sext_string) + int + DoGetString(__GLXclientState * cl, GLbyte * pc, GLboolean need_swap) + { +- ClientPtr client; ++ ClientPtr client = cl->client; + __GLXcontext *cx; + GLenum name; + const char *string; +@@ -327,6 +339,8 @@ DoGetString(__GLXclientState * cl, GLbyte * pc, GLboolean need_swap) + char *buf = NULL, *buf1 = NULL; + GLint length = 0; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 4); ++ + /* If the client has the opposite byte order, swap the contextTag and + * the name. + */ +@@ -343,7 +357,6 @@ DoGetString(__GLXclientState * cl, GLbyte * pc, GLboolean need_swap) + pc += __GLX_SINGLE_HDR_SIZE; + name = *(GLenum *) (pc + 0); + string = (const char *) glGetString(name); +- client = cl->client; + + if (string == NULL) + string = ""; +diff --git a/glx/single2swap.c b/glx/single2swap.c +index 764501f..5349069 100644 +--- a/glx/single2swap.c ++++ b/glx/single2swap.c +@@ -41,6 +41,7 @@ + int + __glXDispSwap_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc) + { ++ ClientPtr client = cl->client; + GLsizei size; + GLenum type; + +@@ -48,6 +49,8 @@ __glXDispSwap_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc) + __GLXcontext *cx; + int error; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 8); ++ + __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { +@@ -77,12 +80,15 @@ __glXDispSwap_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc) + int + __glXDispSwap_SelectBuffer(__GLXclientState * cl, GLbyte * pc) + { ++ ClientPtr client = cl->client; + __GLXcontext *cx; + GLsizei size; + + __GLX_DECLARE_SWAP_VARIABLES; + int error; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 4); ++ + __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { +@@ -109,7 +115,7 @@ __glXDispSwap_SelectBuffer(__GLXclientState * cl, GLbyte * pc) + int + __glXDispSwap_RenderMode(__GLXclientState * cl, GLbyte * pc) + { +- ClientPtr client; ++ ClientPtr client = cl->client; + __GLXcontext *cx; + xGLXRenderModeReply reply; + GLint nitems = 0, retBytes = 0, retval, newModeCheck; +@@ -120,6 +126,8 @@ __glXDispSwap_RenderMode(__GLXclientState * cl, GLbyte * pc) + __GLX_DECLARE_SWAP_ARRAY_VARIABLES; + int error; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 4); ++ + __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { +@@ -200,7 +208,6 @@ __glXDispSwap_RenderMode(__GLXclientState * cl, GLbyte * pc) + ** selection array, as per the API for glRenderMode itself. + */ + noChangeAllowed:; +- client = cl->client; + reply = (xGLXRenderModeReply) { + .type = X_Reply, + .sequenceNumber = client->sequence, +@@ -224,11 +231,14 @@ __glXDispSwap_RenderMode(__GLXclientState * cl, GLbyte * pc) + int + __glXDispSwap_Flush(__GLXclientState * cl, GLbyte * pc) + { ++ ClientPtr client = cl->client; + __GLXcontext *cx; + int error; + + __GLX_DECLARE_SWAP_VARIABLES; + ++ REQUEST_SIZE_MATCH(xGLXSingleReq); ++ + __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { +@@ -243,12 +253,14 @@ __glXDispSwap_Flush(__GLXclientState * cl, GLbyte * pc) + int + __glXDispSwap_Finish(__GLXclientState * cl, GLbyte * pc) + { ++ ClientPtr client = cl->client; + __GLXcontext *cx; +- ClientPtr client; + int error; + + __GLX_DECLARE_SWAP_VARIABLES; + ++ REQUEST_SIZE_MATCH(xGLXSingleReq); ++ + __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { +@@ -260,7 +272,6 @@ __glXDispSwap_Finish(__GLXclientState * cl, GLbyte * pc) + cx->hasUnflushedCommands = GL_FALSE; + + /* Send empty reply packet to indicate finish is finished */ +- client = cl->client; + __GLX_BEGIN_REPLY(0); + __GLX_PUT_RETVAL(0); + __GLX_SWAP_REPLY_HEADER(); +diff --git a/glx/singlepix.c b/glx/singlepix.c +index 8b6c261..54ed7fd 100644 +--- a/glx/singlepix.c ++++ b/glx/singlepix.c +@@ -51,6 +51,8 @@ __glXDisp_ReadPixels(__GLXclientState * cl, GLbyte * pc) + int error; + char *answer, answerBuffer[200]; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 28); ++ + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { + return error; +@@ -100,6 +102,8 @@ __glXDisp_GetTexImage(__GLXclientState * cl, GLbyte * pc) + char *answer, answerBuffer[200]; + GLint width = 0, height = 0, depth = 1; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 20); ++ + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { + return error; +@@ -157,6 +161,8 @@ __glXDisp_GetPolygonStipple(__GLXclientState * cl, GLbyte * pc) + GLubyte answerBuffer[200]; + char *answer; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 4); ++ + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { + return error; +@@ -217,15 +223,13 @@ GetSeparableFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) + compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1); + compsize2 = __glGetTexImage_size(target, 1, format, type, height, 1, 1); + +- if (compsize < 0) ++ if ((compsize = safe_pad(compsize)) < 0) + return BadLength; +- if (compsize2 < 0) ++ if ((compsize2 = safe_pad(compsize2)) < 0) + return BadLength; +- compsize = __GLX_PAD(compsize); +- compsize2 = __GLX_PAD(compsize2); + + glPixelStorei(GL_PACK_SWAP_BYTES, swapBytes); +- __GLX_GET_ANSWER_BUFFER(answer, cl, compsize + compsize2, 1); ++ __GLX_GET_ANSWER_BUFFER(answer, cl, safe_add(compsize, compsize2), 1); + __glXClearErrorOccured(); + glGetSeparableFilter(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), + *(GLenum *) (pc + 8), answer, answer + compsize, NULL); +@@ -249,7 +253,8 @@ int + __glXDisp_GetSeparableFilter(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); +- ++ ClientPtr client = cl->client; ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 16); + return GetSeparableFilter(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); + } + +@@ -257,7 +262,8 @@ int + __glXDisp_GetSeparableFilterEXT(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); +- ++ ClientPtr client = cl->client; ++ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); + return GetSeparableFilter(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); + } + +@@ -323,7 +329,8 @@ int + __glXDisp_GetConvolutionFilter(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); +- ++ ClientPtr client = cl->client; ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 16); + return GetConvolutionFilter(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); + } + +@@ -331,7 +338,8 @@ int + __glXDisp_GetConvolutionFilterEXT(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); +- ++ ClientPtr client = cl->client; ++ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); + return GetConvolutionFilter(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); + } + +@@ -390,7 +398,8 @@ int + __glXDisp_GetHistogram(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); +- ++ ClientPtr client = cl->client; ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 16); + return GetHistogram(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); + } + +@@ -398,7 +407,8 @@ int + __glXDisp_GetHistogramEXT(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); +- ++ ClientPtr client = cl->client; ++ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); + return GetHistogram(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); + } + +@@ -450,7 +460,8 @@ int + __glXDisp_GetMinmax(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); +- ++ ClientPtr client = cl->client; ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 16); + return GetMinmax(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); + } + +@@ -458,7 +469,8 @@ int + __glXDisp_GetMinmaxEXT(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); +- ++ ClientPtr client = cl->client; ++ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); + return GetMinmax(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); + } + +@@ -517,7 +529,8 @@ int + __glXDisp_GetColorTable(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); +- ++ ClientPtr client = cl->client; ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 16); + return GetColorTable(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); + } + +@@ -525,6 +538,7 @@ int + __glXDisp_GetColorTableSGI(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); +- ++ ClientPtr client = cl->client; ++ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); + return GetColorTable(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); + } +diff --git a/glx/singlepixswap.c b/glx/singlepixswap.c +index 8dc304f..9eff592 100644 +--- a/glx/singlepixswap.c ++++ b/glx/singlepixswap.c +@@ -53,6 +53,8 @@ __glXDispSwap_ReadPixels(__GLXclientState * cl, GLbyte * pc) + int error; + char *answer, answerBuffer[200]; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 28); ++ + __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { +@@ -114,6 +116,8 @@ __glXDispSwap_GetTexImage(__GLXclientState * cl, GLbyte * pc) + char *answer, answerBuffer[200]; + GLint width = 0, height = 0, depth = 1; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 20); ++ + __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { +@@ -184,6 +188,8 @@ __glXDispSwap_GetPolygonStipple(__GLXclientState * cl, GLbyte * pc) + + __GLX_DECLARE_SWAP_VARIABLES; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 4); ++ + __GLX_SWAP_INT(&((xGLXSingleReq *) pc)->contextTag); + cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); + if (!cx) { +@@ -251,15 +257,13 @@ GetSeparableFilter(__GLXclientState * cl, GLbyte * pc, GLXContextTag tag) + compsize = __glGetTexImage_size(target, 1, format, type, width, 1, 1); + compsize2 = __glGetTexImage_size(target, 1, format, type, height, 1, 1); + +- if (compsize < 0) ++ if ((compsize = safe_pad(compsize)) < 0) + return BadLength; +- if (compsize2 < 0) ++ if ((compsize2 = safe_pad(compsize2)) < 0) + return BadLength; +- compsize = __GLX_PAD(compsize); +- compsize2 = __GLX_PAD(compsize2); + + glPixelStorei(GL_PACK_SWAP_BYTES, !swapBytes); +- __GLX_GET_ANSWER_BUFFER(answer, cl, compsize + compsize2, 1); ++ __GLX_GET_ANSWER_BUFFER(answer, cl, safe_add(compsize, compsize2), 1); + __glXClearErrorOccured(); + glGetSeparableFilter(*(GLenum *) (pc + 0), *(GLenum *) (pc + 4), + *(GLenum *) (pc + 8), answer, answer + compsize, NULL); +@@ -285,7 +289,9 @@ int + __glXDispSwap_GetSeparableFilter(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); ++ ClientPtr client = cl->client; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 16); + return GetSeparableFilter(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); + } + +@@ -293,7 +299,9 @@ int + __glXDispSwap_GetSeparableFilterEXT(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); ++ ClientPtr client = cl->client; + ++ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); + return GetSeparableFilter(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); + } + +@@ -367,7 +375,9 @@ int + __glXDispSwap_GetConvolutionFilter(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); ++ ClientPtr client = cl->client; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 16); + return GetConvolutionFilter(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); + } + +@@ -375,7 +385,9 @@ int + __glXDispSwap_GetConvolutionFilterEXT(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); ++ ClientPtr client = cl->client; + ++ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); + return GetConvolutionFilter(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); + } + +@@ -441,7 +453,9 @@ int + __glXDispSwap_GetHistogram(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); ++ ClientPtr client = cl->client; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 16); + return GetHistogram(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); + } + +@@ -449,7 +463,9 @@ int + __glXDispSwap_GetHistogramEXT(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); ++ ClientPtr client = cl->client; + ++ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); + return GetHistogram(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); + } + +@@ -507,7 +523,9 @@ int + __glXDispSwap_GetMinmax(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); ++ ClientPtr client = cl->client; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 16); + return GetMinmax(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); + } + +@@ -515,7 +533,9 @@ int + __glXDispSwap_GetMinmaxEXT(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); ++ ClientPtr client = cl->client; + ++ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); + return GetMinmax(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); + } + +@@ -581,7 +601,9 @@ int + __glXDispSwap_GetColorTable(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_SINGLE_CONTEXT_TAG(pc); ++ ClientPtr client = cl->client; + ++ REQUEST_FIXED_SIZE(xGLXSingleReq, 16); + return GetColorTable(cl, pc + __GLX_SINGLE_HDR_SIZE, tag); + } + +@@ -589,6 +611,8 @@ int + __glXDispSwap_GetColorTableSGI(__GLXclientState * cl, GLbyte * pc) + { + const GLXContextTag tag = __GLX_GET_VENDPRIV_CONTEXT_TAG(pc); ++ ClientPtr client = cl->client; + ++ REQUEST_FIXED_SIZE(xGLXVendorPrivateReq, 16); + return GetColorTable(cl, pc + __GLX_VENDPRIV_HDR_SIZE, tag); + } +-- +1.9.3 + diff --git a/SOURCES/0031-glx-Fix-mask-truncation-in-__glXGetAnswerBuffer-CVE-.patch b/SOURCES/0031-glx-Fix-mask-truncation-in-__glXGetAnswerBuffer-CVE-.patch new file mode 100644 index 0000000..cdbbba1 --- /dev/null +++ b/SOURCES/0031-glx-Fix-mask-truncation-in-__glXGetAnswerBuffer-CVE-.patch @@ -0,0 +1,35 @@ +From 32a1e43ecfe456363ddcb87cc39ef80bcb44fd55 Mon Sep 17 00:00:00 2001 +From: Robert Morell +Date: Wed, 12 Nov 2014 18:51:43 -0800 +Subject: [PATCH 31/33] glx: Fix mask truncation in __glXGetAnswerBuffer + [CVE-2014-8093 6/6] + +On a system where sizeof(unsigned) != sizeof(intptr_t), the unary +bitwise not operation will result in a mask that clears all high bits +from temp_buf in the expression: + temp_buf = (temp_buf + mask) & ~mask; + +Signed-off-by: Robert Morell +Reviewed-by: Alan Coopersmith +Signed-off-by: Alan Coopersmith +Signed-off-by: Fedora X Ninjas +--- + glx/indirect_util.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/glx/indirect_util.c b/glx/indirect_util.c +index 183af83..cebb782 100644 +--- a/glx/indirect_util.c ++++ b/glx/indirect_util.c +@@ -73,7 +73,7 @@ __glXGetAnswerBuffer(__GLXclientState * cl, size_t required_size, + void *local_buffer, size_t local_size, unsigned alignment) + { + void *buffer = local_buffer; +- const unsigned mask = alignment - 1; ++ const intptr_t mask = alignment - 1; + + if (local_size < required_size) { + size_t worst_case_size; +-- +1.9.3 + diff --git a/SOURCES/0032-glx-Length-checking-for-RenderLarge-requests-v2-CVE-.patch b/SOURCES/0032-glx-Length-checking-for-RenderLarge-requests-v2-CVE-.patch new file mode 100644 index 0000000..e057a3b --- /dev/null +++ b/SOURCES/0032-glx-Length-checking-for-RenderLarge-requests-v2-CVE-.patch @@ -0,0 +1,159 @@ +From 8f27c9536131c71dddc120344ed5cd3643e99135 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:43 -0500 +Subject: [PATCH 32/33] glx: Length checking for RenderLarge requests (v2) + [CVE-2014-8098 3/8] + +This is a half-measure until we start passing request length into the +varsize function, but it's better than the nothing we had before. + +v2: Verify that there's at least a large render header's worth of +dataBytes (Julien Cristau) + +Reviewed-by: Michal Srb +Reviewed-by: Andy Ritger +Signed-off-by: Adam Jackson +Signed-off-by: Alan Coopersmith +Signed-off-by: Fedora X Ninjas +--- + glx/glxcmds.c | 57 ++++++++++++++++++++++++++++++++++----------------------- + 1 file changed, 34 insertions(+), 23 deletions(-) + +diff --git a/glx/glxcmds.c b/glx/glxcmds.c +index 5b37e37..317e113 100644 +--- a/glx/glxcmds.c ++++ b/glx/glxcmds.c +@@ -2099,6 +2099,8 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc) + + __GLX_DECLARE_SWAP_VARIABLES; + ++ REQUEST_AT_LEAST_SIZE(xGLXRenderLargeReq); ++ + req = (xGLXRenderLargeReq *) pc; + if (client->swapped) { + __GLX_SWAP_SHORT(&req->length); +@@ -2114,12 +2116,14 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc) + __glXResetLargeCommandStatus(cl); + return error; + } ++ if (safe_pad(req->dataBytes) < 0) ++ return BadLength; + dataBytes = req->dataBytes; + + /* + ** Check the request length. + */ +- if ((req->length << 2) != __GLX_PAD(dataBytes) + sz_xGLXRenderLargeReq) { ++ if ((req->length << 2) != safe_pad(dataBytes) + sz_xGLXRenderLargeReq) { + client->errorValue = req->length; + /* Reset in case this isn't 1st request. */ + __glXResetLargeCommandStatus(cl); +@@ -2129,7 +2133,7 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc) + + if (cl->largeCmdRequestsSoFar == 0) { + __GLXrenderSizeData entry; +- int extra; ++ int extra = 0; + size_t cmdlen; + int err; + +@@ -2142,13 +2146,17 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc) + return __glXError(GLXBadLargeRequest); + } + ++ if (dataBytes < __GLX_RENDER_LARGE_HDR_SIZE) ++ return BadLength; ++ + hdr = (__GLXrenderLargeHeader *) pc; + if (client->swapped) { + __GLX_SWAP_INT(&hdr->length); + __GLX_SWAP_INT(&hdr->opcode); + } +- cmdlen = hdr->length; + opcode = hdr->opcode; ++ if ((cmdlen = safe_pad(hdr->length)) < 0) ++ return BadLength; + + /* + ** Check for core opcodes and grab entry data. +@@ -2170,17 +2178,13 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc) + if (extra < 0) { + return BadLength; + } +- /* large command's header is 4 bytes longer, so add 4 */ +- if (cmdlen != __GLX_PAD(entry.bytes + 4 + extra)) { +- return BadLength; +- } + } +- else { +- /* constant size command */ +- if (cmdlen != __GLX_PAD(entry.bytes + 4)) { +- return BadLength; +- } ++ ++ /* the +4 is safe because we know entry.bytes is small */ ++ if (cmdlen != safe_pad(safe_add(entry.bytes + 4, extra))) { ++ return BadLength; + } ++ + /* + ** Make enough space in the buffer, then copy the entire request. + */ +@@ -2207,6 +2211,7 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc) + ** We are receiving subsequent (i.e. not the first) requests of a + ** multi request command. + */ ++ int bytesSoFar; /* including this packet */ + + /* + ** Check the request number and the total request count. +@@ -2225,11 +2230,18 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc) + /* + ** Check that we didn't get too much data. + */ +- if ((cl->largeCmdBytesSoFar + dataBytes) > cl->largeCmdBytesTotal) { ++ if ((bytesSoFar = safe_add(cl->largeCmdBytesSoFar, dataBytes)) < 0) { ++ client->errorValue = dataBytes; ++ __glXResetLargeCommandStatus(cl); ++ return __glXError(GLXBadLargeRequest); ++ } ++ ++ if (bytesSoFar > cl->largeCmdBytesTotal) { + client->errorValue = dataBytes; + __glXResetLargeCommandStatus(cl); + return __glXError(GLXBadLargeRequest); + } ++ + memcpy(cl->largeCmdBuf + cl->largeCmdBytesSoFar, pc, dataBytes); + cl->largeCmdBytesSoFar += dataBytes; + cl->largeCmdRequestsSoFar++; +@@ -2241,17 +2253,16 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc) + ** This is the last request; it must have enough bytes to complete + ** the command. + */ +- /* NOTE: the two pad macros have been added below; they are needed +- ** because the client library pads the total byte count, but not +- ** the per-request byte counts. The Protocol Encoding says the +- ** total byte count should not be padded, so a proposal will be +- ** made to the ARB to relax the padding constraint on the total +- ** byte count, thus preserving backward compatibility. Meanwhile, +- ** the padding done below fixes a bug that did not allow +- ** large commands of odd sizes to be accepted by the server. ++ /* NOTE: the pad macro below is needed because the client library ++ ** pads the total byte count, but not the per-request byte counts. ++ ** The Protocol Encoding says the total byte count should not be ++ ** padded, so a proposal will be made to the ARB to relax the ++ ** padding constraint on the total byte count, thus preserving ++ ** backward compatibility. Meanwhile, the padding done below ++ ** fixes a bug that did not allow large commands of odd sizes to ++ ** be accepted by the server. + */ +- if (__GLX_PAD(cl->largeCmdBytesSoFar) != +- __GLX_PAD(cl->largeCmdBytesTotal)) { ++ if (safe_pad(cl->largeCmdBytesSoFar) != cl->largeCmdBytesTotal) { + client->errorValue = dataBytes; + __glXResetLargeCommandStatus(cl); + return __glXError(GLXBadLargeRequest); +-- +1.9.3 + diff --git a/SOURCES/0033-glx-Pass-remaining-request-length-into-varsize-v2-CV.patch b/SOURCES/0033-glx-Pass-remaining-request-length-into-varsize-v2-CV.patch new file mode 100644 index 0000000..f0d0bdd --- /dev/null +++ b/SOURCES/0033-glx-Pass-remaining-request-length-into-varsize-v2-CV.patch @@ -0,0 +1,917 @@ +From 58b89d38df58b11d8492af605b571b4232761220 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:48 -0500 +Subject: [PATCH 33/33] glx: Pass remaining request length into ->varsize (v2) + [CVE-2014-8098 8/8] + +v2: Handle more multiplies in indirect_reqsize.c (Julien Cristau) + +Reviewed-by: Julien Cristau +Reviewed-by: Michal Srb +Reviewed-by: Andy Ritger +Signed-off-by: Adam Jackson +Signed-off-by: Alan Coopersmith +Signed-off-by: Fedora X Ninjas +--- + glx/glxcmds.c | 7 +- + glx/glxserver.h | 2 +- + glx/indirect_reqsize.c | 142 +++++++++++++++++++------------------- + glx/indirect_reqsize.h | 181 ++++++++++++++++++++++++++++++------------------- + glx/rensize.c | 27 +++++--- + 5 files changed, 205 insertions(+), 154 deletions(-) + +diff --git a/glx/glxcmds.c b/glx/glxcmds.c +index 317e113..e3bff67 100644 +--- a/glx/glxcmds.c ++++ b/glx/glxcmds.c +@@ -2057,7 +2057,8 @@ __glXDisp_Render(__GLXclientState * cl, GLbyte * pc) + if (entry.varsize) { + /* variable size command */ + extra = (*entry.varsize) (pc + __GLX_RENDER_HDR_SIZE, +- client->swapped); ++ client->swapped, ++ left - __GLX_RENDER_HDR_SIZE); + if (extra < 0) { + return BadLength; + } +@@ -2134,6 +2135,7 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc) + if (cl->largeCmdRequestsSoFar == 0) { + __GLXrenderSizeData entry; + int extra = 0; ++ int left = (req->length << 2) - sz_xGLXRenderLargeReq; + size_t cmdlen; + int err; + +@@ -2174,7 +2176,8 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc) + ** will be in the 1st request, so it's okay to do this. + */ + extra = (*entry.varsize) (pc + __GLX_RENDER_LARGE_HDR_SIZE, +- client->swapped); ++ client->swapped, ++ left - __GLX_RENDER_LARGE_HDR_SIZE); + if (extra < 0) { + return BadLength; + } +diff --git a/glx/glxserver.h b/glx/glxserver.h +index 14c5dda..0083721 100644 +--- a/glx/glxserver.h ++++ b/glx/glxserver.h +@@ -179,7 +179,7 @@ typedef int (*__GLXprocPtr) (__GLXclientState *, char *pc); + /* + * Tables for computing the size of each rendering command. + */ +-typedef int (*gl_proto_size_func) (const GLbyte *, Bool); ++typedef int (*gl_proto_size_func) (const GLbyte *, Bool, int); + + typedef struct { + int bytes; +diff --git a/glx/indirect_reqsize.c b/glx/indirect_reqsize.c +index 026afb6..092a421 100644 +--- a/glx/indirect_reqsize.c ++++ b/glx/indirect_reqsize.c +@@ -31,24 +31,22 @@ + #include "indirect_size.h" + #include "indirect_reqsize.h" + +-#define __GLX_PAD(x) (((x) + 3) & ~3) +- + #if defined(__CYGWIN__) || defined(__MINGW32__) + #undef HAVE_ALIAS + #endif + #ifdef HAVE_ALIAS + #define ALIAS2(from,to) \ +- GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap ) \ ++ GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap, int reqlen ) \ + __attribute__ ((alias( # to ))); + #define ALIAS(from,to) ALIAS2( from, __glX ## to ## ReqSize ) + #else + #define ALIAS(from,to) \ +- GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap ) \ +- { return __glX ## to ## ReqSize( pc, swap ); } ++ GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap, int reqlen ) \ ++ { return __glX ## to ## ReqSize( pc, swap, reqlen ); } + #endif + + int +-__glXCallListsReqSize(const GLbyte * pc, Bool swap) ++__glXCallListsReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei n = *(GLsizei *) (pc + 0); + GLenum type = *(GLenum *) (pc + 4); +@@ -60,11 +58,11 @@ __glXCallListsReqSize(const GLbyte * pc, Bool swap) + } + + compsize = __glCallLists_size(type); +- return __GLX_PAD((compsize * n)); ++ return safe_pad(safe_mul(compsize, n)); + } + + int +-__glXBitmapReqSize(const GLbyte * pc, Bool swap) ++__glXBitmapReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLint row_length = *(GLint *) (pc + 4); + GLint image_height = 0; +@@ -88,7 +86,7 @@ __glXBitmapReqSize(const GLbyte * pc, Bool swap) + } + + int +-__glXFogfvReqSize(const GLbyte * pc, Bool swap) ++__glXFogfvReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum pname = *(GLenum *) (pc + 0); + GLsizei compsize; +@@ -98,11 +96,11 @@ __glXFogfvReqSize(const GLbyte * pc, Bool swap) + } + + compsize = __glFogfv_size(pname); +- return __GLX_PAD((compsize * 4)); ++ return safe_pad(safe_mul(compsize, 4)); + } + + int +-__glXLightfvReqSize(const GLbyte * pc, Bool swap) ++__glXLightfvReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum pname = *(GLenum *) (pc + 4); + GLsizei compsize; +@@ -112,11 +110,11 @@ __glXLightfvReqSize(const GLbyte * pc, Bool swap) + } + + compsize = __glLightfv_size(pname); +- return __GLX_PAD((compsize * 4)); ++ return safe_pad(safe_mul(compsize, 4)); + } + + int +-__glXLightModelfvReqSize(const GLbyte * pc, Bool swap) ++__glXLightModelfvReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum pname = *(GLenum *) (pc + 0); + GLsizei compsize; +@@ -126,11 +124,11 @@ __glXLightModelfvReqSize(const GLbyte * pc, Bool swap) + } + + compsize = __glLightModelfv_size(pname); +- return __GLX_PAD((compsize * 4)); ++ return safe_pad(safe_mul(compsize, 4)); + } + + int +-__glXMaterialfvReqSize(const GLbyte * pc, Bool swap) ++__glXMaterialfvReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum pname = *(GLenum *) (pc + 4); + GLsizei compsize; +@@ -140,11 +138,11 @@ __glXMaterialfvReqSize(const GLbyte * pc, Bool swap) + } + + compsize = __glMaterialfv_size(pname); +- return __GLX_PAD((compsize * 4)); ++ return safe_pad(safe_mul(compsize, 4)); + } + + int +-__glXPolygonStippleReqSize(const GLbyte * pc, Bool swap) ++__glXPolygonStippleReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLint row_length = *(GLint *) (pc + 4); + GLint image_height = 0; +@@ -164,7 +162,7 @@ __glXPolygonStippleReqSize(const GLbyte * pc, Bool swap) + } + + int +-__glXTexParameterfvReqSize(const GLbyte * pc, Bool swap) ++__glXTexParameterfvReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum pname = *(GLenum *) (pc + 4); + GLsizei compsize; +@@ -174,11 +172,11 @@ __glXTexParameterfvReqSize(const GLbyte * pc, Bool swap) + } + + compsize = __glTexParameterfv_size(pname); +- return __GLX_PAD((compsize * 4)); ++ return safe_pad(safe_mul(compsize, 4)); + } + + int +-__glXTexImage1DReqSize(const GLbyte * pc, Bool swap) ++__glXTexImage1DReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLint row_length = *(GLint *) (pc + 4); + GLint image_height = 0; +@@ -206,7 +204,7 @@ __glXTexImage1DReqSize(const GLbyte * pc, Bool swap) + } + + int +-__glXTexImage2DReqSize(const GLbyte * pc, Bool swap) ++__glXTexImage2DReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLint row_length = *(GLint *) (pc + 4); + GLint image_height = 0; +@@ -236,7 +234,7 @@ __glXTexImage2DReqSize(const GLbyte * pc, Bool swap) + } + + int +-__glXTexEnvfvReqSize(const GLbyte * pc, Bool swap) ++__glXTexEnvfvReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum pname = *(GLenum *) (pc + 4); + GLsizei compsize; +@@ -246,11 +244,11 @@ __glXTexEnvfvReqSize(const GLbyte * pc, Bool swap) + } + + compsize = __glTexEnvfv_size(pname); +- return __GLX_PAD((compsize * 4)); ++ return safe_pad(safe_mul(compsize, 4)); + } + + int +-__glXTexGendvReqSize(const GLbyte * pc, Bool swap) ++__glXTexGendvReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum pname = *(GLenum *) (pc + 4); + GLsizei compsize; +@@ -260,11 +258,11 @@ __glXTexGendvReqSize(const GLbyte * pc, Bool swap) + } + + compsize = __glTexGendv_size(pname); +- return __GLX_PAD((compsize * 8)); ++ return safe_pad(safe_mul(compsize, 8)); + } + + int +-__glXTexGenfvReqSize(const GLbyte * pc, Bool swap) ++__glXTexGenfvReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum pname = *(GLenum *) (pc + 4); + GLsizei compsize; +@@ -274,11 +272,11 @@ __glXTexGenfvReqSize(const GLbyte * pc, Bool swap) + } + + compsize = __glTexGenfv_size(pname); +- return __GLX_PAD((compsize * 4)); ++ return safe_pad(safe_mul(compsize, 4)); + } + + int +-__glXPixelMapfvReqSize(const GLbyte * pc, Bool swap) ++__glXPixelMapfvReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei mapsize = *(GLsizei *) (pc + 4); + +@@ -286,11 +284,11 @@ __glXPixelMapfvReqSize(const GLbyte * pc, Bool swap) + mapsize = bswap_32(mapsize); + } + +- return __GLX_PAD((mapsize * 4)); ++ return safe_pad(safe_mul(mapsize, 4)); + } + + int +-__glXPixelMapusvReqSize(const GLbyte * pc, Bool swap) ++__glXPixelMapusvReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei mapsize = *(GLsizei *) (pc + 4); + +@@ -298,11 +296,11 @@ __glXPixelMapusvReqSize(const GLbyte * pc, Bool swap) + mapsize = bswap_32(mapsize); + } + +- return __GLX_PAD((mapsize * 2)); ++ return safe_pad(safe_mul(mapsize, 2)); + } + + int +-__glXDrawPixelsReqSize(const GLbyte * pc, Bool swap) ++__glXDrawPixelsReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLint row_length = *(GLint *) (pc + 4); + GLint image_height = 0; +@@ -330,7 +328,7 @@ __glXDrawPixelsReqSize(const GLbyte * pc, Bool swap) + } + + int +-__glXPrioritizeTexturesReqSize(const GLbyte * pc, Bool swap) ++__glXPrioritizeTexturesReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei n = *(GLsizei *) (pc + 0); + +@@ -338,11 +336,11 @@ __glXPrioritizeTexturesReqSize(const GLbyte * pc, Bool swap) + n = bswap_32(n); + } + +- return __GLX_PAD((n * 4) + (n * 4)); ++ return safe_pad(safe_add(safe_mul(n, 4), safe_mul(n, 4))); + } + + int +-__glXTexSubImage1DReqSize(const GLbyte * pc, Bool swap) ++__glXTexSubImage1DReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLint row_length = *(GLint *) (pc + 4); + GLint image_height = 0; +@@ -370,7 +368,7 @@ __glXTexSubImage1DReqSize(const GLbyte * pc, Bool swap) + } + + int +-__glXTexSubImage2DReqSize(const GLbyte * pc, Bool swap) ++__glXTexSubImage2DReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLint row_length = *(GLint *) (pc + 4); + GLint image_height = 0; +@@ -400,7 +398,7 @@ __glXTexSubImage2DReqSize(const GLbyte * pc, Bool swap) + } + + int +-__glXColorTableReqSize(const GLbyte * pc, Bool swap) ++__glXColorTableReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLint row_length = *(GLint *) (pc + 4); + GLint image_height = 0; +@@ -428,7 +426,7 @@ __glXColorTableReqSize(const GLbyte * pc, Bool swap) + } + + int +-__glXColorTableParameterfvReqSize(const GLbyte * pc, Bool swap) ++__glXColorTableParameterfvReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum pname = *(GLenum *) (pc + 4); + GLsizei compsize; +@@ -438,11 +436,11 @@ __glXColorTableParameterfvReqSize(const GLbyte * pc, Bool swap) + } + + compsize = __glColorTableParameterfv_size(pname); +- return __GLX_PAD((compsize * 4)); ++ return safe_pad(safe_mul(compsize, 4)); + } + + int +-__glXColorSubTableReqSize(const GLbyte * pc, Bool swap) ++__glXColorSubTableReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLint row_length = *(GLint *) (pc + 4); + GLint image_height = 0; +@@ -470,7 +468,7 @@ __glXColorSubTableReqSize(const GLbyte * pc, Bool swap) + } + + int +-__glXConvolutionFilter1DReqSize(const GLbyte * pc, Bool swap) ++__glXConvolutionFilter1DReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLint row_length = *(GLint *) (pc + 4); + GLint image_height = 0; +@@ -498,7 +496,7 @@ __glXConvolutionFilter1DReqSize(const GLbyte * pc, Bool swap) + } + + int +-__glXConvolutionFilter2DReqSize(const GLbyte * pc, Bool swap) ++__glXConvolutionFilter2DReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLint row_length = *(GLint *) (pc + 4); + GLint image_height = 0; +@@ -528,7 +526,7 @@ __glXConvolutionFilter2DReqSize(const GLbyte * pc, Bool swap) + } + + int +-__glXConvolutionParameterfvReqSize(const GLbyte * pc, Bool swap) ++__glXConvolutionParameterfvReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum pname = *(GLenum *) (pc + 4); + GLsizei compsize; +@@ -538,11 +536,11 @@ __glXConvolutionParameterfvReqSize(const GLbyte * pc, Bool swap) + } + + compsize = __glConvolutionParameterfv_size(pname); +- return __GLX_PAD((compsize * 4)); ++ return safe_pad(safe_mul(compsize, 4)); + } + + int +-__glXTexImage3DReqSize(const GLbyte * pc, Bool swap) ++__glXTexImage3DReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLint row_length = *(GLint *) (pc + 4); + GLint image_height = *(GLint *) (pc + 8); +@@ -579,7 +577,7 @@ __glXTexImage3DReqSize(const GLbyte * pc, Bool swap) + } + + int +-__glXTexSubImage3DReqSize(const GLbyte * pc, Bool swap) ++__glXTexSubImage3DReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLint row_length = *(GLint *) (pc + 4); + GLint image_height = *(GLint *) (pc + 8); +@@ -613,7 +611,7 @@ __glXTexSubImage3DReqSize(const GLbyte * pc, Bool swap) + } + + int +-__glXCompressedTexImage1DReqSize(const GLbyte * pc, Bool swap) ++__glXCompressedTexImage1DReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei imageSize = *(GLsizei *) (pc + 20); + +@@ -621,11 +619,11 @@ __glXCompressedTexImage1DReqSize(const GLbyte * pc, Bool swap) + imageSize = bswap_32(imageSize); + } + +- return __GLX_PAD(imageSize); ++ return safe_pad(imageSize); + } + + int +-__glXCompressedTexImage2DReqSize(const GLbyte * pc, Bool swap) ++__glXCompressedTexImage2DReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei imageSize = *(GLsizei *) (pc + 24); + +@@ -633,11 +631,11 @@ __glXCompressedTexImage2DReqSize(const GLbyte * pc, Bool swap) + imageSize = bswap_32(imageSize); + } + +- return __GLX_PAD(imageSize); ++ return safe_pad(imageSize); + } + + int +-__glXCompressedTexImage3DReqSize(const GLbyte * pc, Bool swap) ++__glXCompressedTexImage3DReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei imageSize = *(GLsizei *) (pc + 28); + +@@ -645,11 +643,11 @@ __glXCompressedTexImage3DReqSize(const GLbyte * pc, Bool swap) + imageSize = bswap_32(imageSize); + } + +- return __GLX_PAD(imageSize); ++ return safe_pad(imageSize); + } + + int +-__glXCompressedTexSubImage3DReqSize(const GLbyte * pc, Bool swap) ++__glXCompressedTexSubImage3DReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei imageSize = *(GLsizei *) (pc + 36); + +@@ -657,11 +655,11 @@ __glXCompressedTexSubImage3DReqSize(const GLbyte * pc, Bool swap) + imageSize = bswap_32(imageSize); + } + +- return __GLX_PAD(imageSize); ++ return safe_pad(imageSize); + } + + int +-__glXPointParameterfvReqSize(const GLbyte * pc, Bool swap) ++__glXPointParameterfvReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum pname = *(GLenum *) (pc + 0); + GLsizei compsize; +@@ -671,11 +669,11 @@ __glXPointParameterfvReqSize(const GLbyte * pc, Bool swap) + } + + compsize = __glPointParameterfv_size(pname); +- return __GLX_PAD((compsize * 4)); ++ return safe_pad(safe_mul(compsize, 4)); + } + + int +-__glXDrawBuffersReqSize(const GLbyte * pc, Bool swap) ++__glXDrawBuffersReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei n = *(GLsizei *) (pc + 0); + +@@ -683,11 +681,11 @@ __glXDrawBuffersReqSize(const GLbyte * pc, Bool swap) + n = bswap_32(n); + } + +- return __GLX_PAD((n * 4)); ++ return safe_pad(safe_mul(n, 4)); + } + + int +-__glXProgramStringARBReqSize(const GLbyte * pc, Bool swap) ++__glXProgramStringARBReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei len = *(GLsizei *) (pc + 8); + +@@ -695,11 +693,11 @@ __glXProgramStringARBReqSize(const GLbyte * pc, Bool swap) + len = bswap_32(len); + } + +- return __GLX_PAD(len); ++ return safe_pad(len); + } + + int +-__glXVertexAttribs1dvNVReqSize(const GLbyte * pc, Bool swap) ++__glXVertexAttribs1dvNVReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei n = *(GLsizei *) (pc + 4); + +@@ -707,11 +705,11 @@ __glXVertexAttribs1dvNVReqSize(const GLbyte * pc, Bool swap) + n = bswap_32(n); + } + +- return __GLX_PAD((n * 8)); ++ return safe_pad(safe_mul(n, 8)); + } + + int +-__glXVertexAttribs2dvNVReqSize(const GLbyte * pc, Bool swap) ++__glXVertexAttribs2dvNVReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei n = *(GLsizei *) (pc + 4); + +@@ -719,11 +717,11 @@ __glXVertexAttribs2dvNVReqSize(const GLbyte * pc, Bool swap) + n = bswap_32(n); + } + +- return __GLX_PAD((n * 16)); ++ return safe_pad(safe_mul(n, 16)); + } + + int +-__glXVertexAttribs3dvNVReqSize(const GLbyte * pc, Bool swap) ++__glXVertexAttribs3dvNVReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei n = *(GLsizei *) (pc + 4); + +@@ -731,11 +729,11 @@ __glXVertexAttribs3dvNVReqSize(const GLbyte * pc, Bool swap) + n = bswap_32(n); + } + +- return __GLX_PAD((n * 24)); ++ return safe_pad(safe_mul(n, 24)); + } + + int +-__glXVertexAttribs3fvNVReqSize(const GLbyte * pc, Bool swap) ++__glXVertexAttribs3fvNVReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei n = *(GLsizei *) (pc + 4); + +@@ -743,11 +741,11 @@ __glXVertexAttribs3fvNVReqSize(const GLbyte * pc, Bool swap) + n = bswap_32(n); + } + +- return __GLX_PAD((n * 12)); ++ return safe_pad(safe_mul(n, 12)); + } + + int +-__glXVertexAttribs3svNVReqSize(const GLbyte * pc, Bool swap) ++__glXVertexAttribs3svNVReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei n = *(GLsizei *) (pc + 4); + +@@ -755,11 +753,11 @@ __glXVertexAttribs3svNVReqSize(const GLbyte * pc, Bool swap) + n = bswap_32(n); + } + +- return __GLX_PAD((n * 6)); ++ return safe_pad(safe_mul(n, 6)); + } + + int +-__glXVertexAttribs4dvNVReqSize(const GLbyte * pc, Bool swap) ++__glXVertexAttribs4dvNVReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei n = *(GLsizei *) (pc + 4); + +@@ -767,7 +765,7 @@ __glXVertexAttribs4dvNVReqSize(const GLbyte * pc, Bool swap) + n = bswap_32(n); + } + +- return __GLX_PAD((n * 32)); ++ return safe_pad(safe_mul(n, 32)); + } + + ALIAS(Fogiv, Fogfv) +diff --git a/glx/indirect_reqsize.h b/glx/indirect_reqsize.h +index 43e1e69..f0d8893 100644 +--- a/glx/indirect_reqsize.h ++++ b/glx/indirect_reqsize.h +@@ -36,115 +36,156 @@ + #define PURE + #endif + +-extern PURE _X_HIDDEN int __glXCallListsReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXBitmapReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXFogfvReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXFogivReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXLightfvReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXLightivReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXLightModelfvReqSize(const GLbyte * pc, +- Bool swap); +-extern PURE _X_HIDDEN int __glXLightModelivReqSize(const GLbyte * pc, +- Bool swap); +-extern PURE _X_HIDDEN int __glXMaterialfvReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXMaterialivReqSize(const GLbyte * pc, Bool swap); ++extern PURE _X_HIDDEN int __glXCallListsReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXBitmapReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXFogfvReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXFogivReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXLightfvReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXLightivReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXLightModelfvReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXLightModelivReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXMaterialfvReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXMaterialivReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXPolygonStippleReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXTexParameterfvReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXTexParameterivReqSize(const GLbyte * pc, +- Bool swap); +-extern PURE _X_HIDDEN int __glXTexImage1DReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXTexImage2DReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXTexEnvfvReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXTexEnvivReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXTexGendvReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXTexGenfvReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXTexGenivReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXMap1dReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXMap1fReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXMap2dReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXMap2fReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXPixelMapfvReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXPixelMapuivReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXPixelMapusvReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXDrawPixelsReqSize(const GLbyte * pc, Bool swap); +-extern PURE _X_HIDDEN int __glXDrawArraysReqSize(const GLbyte * pc, Bool swap); ++ Bool swap, int reqlen); ++extern PURE _X_HIDDEN int __glXTexImage1DReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXTexImage2DReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXTexEnvfvReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXTexEnvivReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXTexGendvReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXTexGenfvReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXTexGenivReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXMap1dReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXMap1fReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXMap2dReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXMap2fReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXPixelMapfvReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXPixelMapuivReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXPixelMapusvReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXDrawPixelsReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); ++extern PURE _X_HIDDEN int __glXDrawArraysReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXPrioritizeTexturesReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXTexSubImage1DReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXTexSubImage2DReqSize(const GLbyte * pc, +- Bool swap); +-extern PURE _X_HIDDEN int __glXColorTableReqSize(const GLbyte * pc, Bool swap); ++ Bool swap, int reqlen); ++extern PURE _X_HIDDEN int __glXColorTableReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXColorTableParameterfvReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXColorTableParameterivReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXColorSubTableReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXConvolutionFilter1DReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXConvolutionFilter2DReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXConvolutionParameterfvReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXConvolutionParameterivReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXSeparableFilter2DReqSize(const GLbyte * pc, +- Bool swap); +-extern PURE _X_HIDDEN int __glXTexImage3DReqSize(const GLbyte * pc, Bool swap); ++ Bool swap, int reqlen); ++extern PURE _X_HIDDEN int __glXTexImage3DReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXTexSubImage3DReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXCompressedTexImage1DReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXCompressedTexImage2DReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXCompressedTexImage3DReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXCompressedTexSubImage1DReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXCompressedTexSubImage2DReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXCompressedTexSubImage3DReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXPointParameterfvReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXPointParameterivReqSize(const GLbyte * pc, +- Bool swap); +-extern PURE _X_HIDDEN int __glXDrawBuffersReqSize(const GLbyte * pc, Bool swap); ++ Bool swap, int reqlen); ++extern PURE _X_HIDDEN int __glXDrawBuffersReqSize(const GLbyte * pc, Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXProgramStringARBReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXDeleteFramebuffersReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXDeleteRenderbuffersReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, ++ int reqlen); + extern PURE _X_HIDDEN int __glXVertexAttribs1dvNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXVertexAttribs1fvNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXVertexAttribs1svNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXVertexAttribs2dvNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXVertexAttribs2fvNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXVertexAttribs2svNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXVertexAttribs3dvNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXVertexAttribs3fvNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXVertexAttribs3svNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXVertexAttribs4dvNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXVertexAttribs4fvNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXVertexAttribs4svNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXVertexAttribs4ubvNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, ++ int reqlen); + + #undef PURE + +diff --git a/glx/rensize.c b/glx/rensize.c +index 6ee0f9c..a532467 100644 +--- a/glx/rensize.c ++++ b/glx/rensize.c +@@ -44,7 +44,7 @@ + ((a & 0xff00U)<<8) | ((a & 0xffU)<<24)) + + int +-__glXMap1dReqSize(const GLbyte * pc, Bool swap) ++__glXMap1dReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum target; + GLint order; +@@ -61,7 +61,7 @@ __glXMap1dReqSize(const GLbyte * pc, Bool swap) + } + + int +-__glXMap1fReqSize(const GLbyte * pc, Bool swap) ++__glXMap1fReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum target; + GLint order; +@@ -86,7 +86,7 @@ Map2Size(int k, int majorOrder, int minorOrder) + } + + int +-__glXMap2dReqSize(const GLbyte * pc, Bool swap) ++__glXMap2dReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum target; + GLint uorder, vorder; +@@ -103,7 +103,7 @@ __glXMap2dReqSize(const GLbyte * pc, Bool swap) + } + + int +-__glXMap2fReqSize(const GLbyte * pc, Bool swap) ++__glXMap2fReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum target; + GLint uorder, vorder; +@@ -359,13 +359,14 @@ __glXTypeSize(GLenum enm) + } + + int +-__glXDrawArraysReqSize(const GLbyte * pc, Bool swap) ++__glXDrawArraysReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + __GLXdispatchDrawArraysHeader *hdr = (__GLXdispatchDrawArraysHeader *) pc; + __GLXdispatchDrawArraysComponentHeader *compHeader; + GLint numVertexes = hdr->numVertexes; + GLint numComponents = hdr->numComponents; + GLint arrayElementSize = 0; ++ GLint x, size; + int i; + + if (swap) { +@@ -374,6 +375,13 @@ __glXDrawArraysReqSize(const GLbyte * pc, Bool swap) + } + + pc += sizeof(__GLXdispatchDrawArraysHeader); ++ reqlen -= sizeof(__GLXdispatchDrawArraysHeader); ++ ++ size = safe_mul(sizeof(__GLXdispatchDrawArraysComponentHeader), ++ numComponents); ++ if (size < 0 || reqlen < 0 || reqlen < size) ++ return -1; ++ + compHeader = (__GLXdispatchDrawArraysComponentHeader *) pc; + + for (i = 0; i < numComponents; i++) { +@@ -417,17 +425,18 @@ __glXDrawArraysReqSize(const GLbyte * pc, Bool swap) + return -1; + } + +- arrayElementSize += __GLX_PAD(numVals * __glXTypeSize(datatype)); ++ x = safe_pad(safe_mul(numVals, __glXTypeSize(datatype))); ++ if ((arrayElementSize = safe_add(arrayElementSize, x)) < 0) ++ return -1; + + pc += sizeof(__GLXdispatchDrawArraysComponentHeader); + } + +- return ((numComponents * sizeof(__GLXdispatchDrawArraysComponentHeader)) + +- (numVertexes * arrayElementSize)); ++ return safe_add(size, safe_mul(numVertexes, arrayElementSize)); + } + + int +-__glXSeparableFilter2DReqSize(const GLbyte * pc, Bool swap) ++__glXSeparableFilter2DReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + __GLXdispatchConvolutionFilterHeader *hdr = + (__GLXdispatchConvolutionFilterHeader *) pc; +-- +1.9.3 + diff --git a/SPECS/xorg-x11-server.spec b/SPECS/xorg-x11-server.spec index 9a9219d..4f29b4f 100644 --- a/SPECS/xorg-x11-server.spec +++ b/SPECS/xorg-x11-server.spec @@ -42,7 +42,7 @@ Summary: X.Org X11 X server Name: xorg-x11-server Version: 1.15.0 -Release: 7%{?gitdate:.%{gitdate}}%{?dist} +Release: 7%{?gitdate:.%{gitdate}}%{?dist}.3 URL: http://www.x.org License: MIT Group: User Interface/X @@ -147,6 +147,45 @@ Patch9103: 0001-randr-attempt-to-fix-primary-on-slave-output.patch Patch9200: 0040-xfree86-Keep-a-non-seat0-X-server-from-touching-VTs-.patch +# CVEs all over. +Patch9999: 0001-glx-check-return-from-__glXGetAnswerBuffer.patch +Patch10000: 0001-unchecked-malloc-may-allow-unauthed-client-to-crash-.patch +Patch10001: 0002-dix-integer-overflow-in-ProcPutImage-CVE-2014-8092-1.patch +Patch10002: 0003-dix-integer-overflow-in-GetHosts-CVE-2014-8092-2-4.patch +Patch10003: 0004-dix-integer-overflow-in-RegionSizeof-CVE-2014-8092-3.patch +Patch10004: 0005-dix-integer-overflow-in-REQUEST_FIXED_SIZE-CVE-2014-.patch +Patch10005: 0006-dri2-integer-overflow-in-ProcDRI2GetBuffers-CVE-2014.patch +Patch10006: 0007-dbe-unvalidated-lengths-in-DbeSwapBuffers-calls-CVE-.patch +Patch10007: 0008-Xi-unvalidated-lengths-in-Xinput-extension-CVE-2014-.patch +Patch10008: 0009-xcmisc-unvalidated-length-in-SProcXCMiscGetXIDList-C.patch +Patch10009: 0010-Xv-unvalidated-lengths-in-XVideo-extension-swapped-p.patch +Patch10010: 0011-dri3-unvalidated-lengths-in-DRI3-extension-swapped-p.patch +Patch10011: 0012-present-unvalidated-lengths-in-Present-extension-pro.patch +Patch10012: 0013-randr-unvalidated-lengths-in-RandR-extension-swapped.patch +Patch10013: 0014-render-check-request-size-before-reading-it-CVE-2014.patch +Patch10014: 0015-render-unvalidated-lengths-in-Render-extn.-swapped-p.patch +Patch10015: 0016-xfixes-unvalidated-length-in-SProcXFixesSelectSelect.patch +Patch10016: 0017-Add-request-length-checking-test-cases-for-some-Xinp.patch +Patch10017: 0018-Add-request-length-checking-test-cases-for-some-Xinp.patch +Patch10018: 0019-Add-REQUEST_FIXED_SIZE-testcases-to-test-misc.c.patch +Patch10019: 0020-glx-Be-more-paranoid-about-variable-length-requests-.patch +Patch10020: 0021-glx-Be-more-strict-about-rejecting-invalid-image-siz.patch +Patch10021: 0022-glx-Additional-paranoia-in-__glXGetAnswerBuffer-__GL.patch +Patch10022: 0023-glx-Fix-image-size-computation-for-EXT_texture_integ.patch +Patch10023: 0024-glx-Add-safe_-add-mul-pad-v3-CVE-2014-8093-4-6.patch +Patch10024: 0025-glx-Length-checking-for-GLXRender-requests-v2-CVE-20.patch +Patch10025: 0026-glx-Integer-overflow-protection-for-non-generated-re.patch +Patch10026: 0027-glx-Top-level-length-checking-for-swapped-VendorPriv.patch +Patch10027: 0028-glx-Request-length-checks-for-SetClientInfoARB-CVE-2.patch +Patch10028: 0029-glx-Length-checking-for-non-generated-vendor-private.patch +Patch10029: 0030-glx-Length-checking-for-non-generated-single-request.patch +Patch10030: 0031-glx-Fix-mask-truncation-in-__glXGetAnswerBuffer-CVE-.patch +Patch10031: 0032-glx-Length-checking-for-RenderLarge-requests-v2-CVE-.patch +Patch10032: 0033-glx-Pass-remaining-request-length-into-varsize-v2-CV.patch +Patch10033: 0001-Missing-parens-in-REQUEST_FIXED_SIZE-macro-CVE-2014-.patch +Patch10034: 0002-dix-GetHosts-bounds-check-using-wrong-pointer-value-.patch + + %global moduledir %{_libdir}/xorg/modules %global drimoduledir %{_libdir}/dri %global sdkdir %{_includedir}/xorg @@ -642,6 +681,11 @@ rm -rf $RPM_BUILD_ROOT %{xserver_source_dir} %changelog +* Wed Dec 10 2014 Adam Jackson 1.15.0-7.3 +- CVE fixes for: CVE-2014-8099, CVE-2014-8098, CVE-2014-8097, CVE-2014-8096, + CVE-2014-8095, CVE-2014-8094, CVE-2014-8093, CVE-2014-8092, CVE-2014-8091, + CVE-2014-8101, CVE-2014-8100, CVE-2014-8103, CVE-2014-8102 + * Thu Feb 27 2014 Jérôme Glisse 1.15.0-7 - Do not open tty on non seat0 (#1053063)