From 8ff4f2f51a6cf07fc33742ce3bee81328896e49b Mon Sep 17 00:00:00 2001 From: Patrick J Volkerding Date: Fri, 25 May 2018 23:29:36 +0000 Subject: Fri May 25 23:29:36 UTC 2018 patches/packages/glibc-zoneinfo-2018e-noarch-2_slack14.1.txz: Rebuilt. Handle removal of US/Pacific-New timezone. If we see that the machine is using this, it will be automatically switched to US/Pacific. --- patches/source/xorg-server/patch/xorg-server.patch | 43 + ...ens-in-REQUEST_FIXED_SIZE-macro-CVE-2014-.patch | 32 + ...lx-check-return-from-__glXGetAnswerBuffer.patch | 173 ++++ ...alloc-may-allow-unauthed-client-to-crash-.patch | 41 + ...s-bounds-check-using-wrong-pointer-value-.patch | 35 + ...-overflow-in-ProcPutImage-CVE-2014-8092-1.patch | 38 + ...er-overflow-in-GetHosts-CVE-2014-8092-2-4.patch | 50 ++ ...-overflow-in-RegionSizeof-CVE-2014-8092-3.patch | 129 +++ ...-overflow-in-REQUEST_FIXED_SIZE-CVE-2014-.patch | 35 + ...r-overflow-in-ProcDRI2GetBuffers-CVE-2014.patch | 36 + ...ated-lengths-in-DbeSwapBuffers-calls-CVE-.patch | 74 ++ ...ted-lengths-in-Xinput-extension-CVE-2014-.patch | 552 ++++++++++++ ...lidated-length-in-SProcXCMiscGetXIDList-C.patch | 28 + ...ted-lengths-in-XVideo-extension-swapped-p.patch | 180 ++++ ...idated-lengths-in-RandR-extension-swapped.patch | 52 ++ ...k-request-size-before-reading-it-CVE-2014.patch | 37 + ...lidated-lengths-in-Render-extn.-swapped-p.patch | 141 ++++ ...lidated-length-in-SProcXFixesSelectSelect.patch | 28 + ...-length-checking-test-cases-for-some-Xinp.patch | 214 +++++ ...-length-checking-test-cases-for-some-Xinp.patch | 90 ++ ...QUEST_FIXED_SIZE-testcases-to-test-misc.c.patch | 75 ++ ...-paranoid-about-variable-length-requests-.patch | 48 ++ ...-strict-about-rejecting-invalid-image-siz.patch | 166 ++++ ...nal-paranoia-in-__glXGetAnswerBuffer-__GL.patch | 60 ++ ...ge-size-computation-for-EXT_texture_integ.patch | 60 ++ ...dd-safe_-add-mul-pad-v3-CVE-2014-8093-4-6.patch | 83 ++ ...checking-for-GLXRender-requests-v2-CVE-20.patch | 76 ++ ...-overflow-protection-for-non-generated-re.patch | 226 +++++ ...el-length-checking-for-swapped-VendorPriv.patch | 52 ++ ...-length-checks-for-SetClientInfoARB-CVE-2.patch | 75 ++ ...checking-for-non-generated-vendor-private.patch | 46 + ...checking-for-non-generated-single-request.patch | 565 +++++++++++++ ...k-truncation-in-__glXGetAnswerBuffer-CVE-.patch | 35 + ...checking-for-RenderLarge-requests-v2-CVE-.patch | 159 ++++ ...maining-request-length-into-varsize-v2-CV.patch | 935 +++++++++++++++++++++ .../xorg-server/x11.startwithblackscreen.diff | 14 + .../xorg-server/xorg-server.CVE-2017-10971.diff | 40 + .../xorg-server/xorg-server.CVE-2017-10972.diff | 36 + .../xorg-server/xorg-server.CVE-2017-12176.diff | 31 + .../xorg-server/xorg-server.CVE-2017-12179_p1.diff | 42 + .../xorg-server/xorg-server.CVE-2017-12179_p2.diff | 46 + .../xorg-server/xorg-server.CVE-2017-12183.diff | 95 +++ .../xorg-server/xorg-server.CVE-2017-13723.diff | 116 +++ 43 files changed, 5089 insertions(+) create mode 100644 patches/source/xorg-server/patch/xorg-server.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0001-Missing-parens-in-REQUEST_FIXED_SIZE-macro-CVE-2014-.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0001-glx-check-return-from-__glXGetAnswerBuffer.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0001-unchecked-malloc-may-allow-unauthed-client-to-crash-.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0002-dix-GetHosts-bounds-check-using-wrong-pointer-value-.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0002-dix-integer-overflow-in-ProcPutImage-CVE-2014-8092-1.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0003-dix-integer-overflow-in-GetHosts-CVE-2014-8092-2-4.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0004-dix-integer-overflow-in-RegionSizeof-CVE-2014-8092-3.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0005-dix-integer-overflow-in-REQUEST_FIXED_SIZE-CVE-2014-.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0006-dri2-integer-overflow-in-ProcDRI2GetBuffers-CVE-2014.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0007-dbe-unvalidated-lengths-in-DbeSwapBuffers-calls-CVE-.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0008-Xi-unvalidated-lengths-in-Xinput-extension-CVE-2014-.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0009-xcmisc-unvalidated-length-in-SProcXCMiscGetXIDList-C.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0010-Xv-unvalidated-lengths-in-XVideo-extension-swapped-p.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0011-randr-unvalidated-lengths-in-RandR-extension-swapped.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0012-render-check-request-size-before-reading-it-CVE-2014.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0013-render-unvalidated-lengths-in-Render-extn.-swapped-p.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0014-xfixes-unvalidated-length-in-SProcXFixesSelectSelect.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0015-Add-request-length-checking-test-cases-for-some-Xinp.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0016-Add-request-length-checking-test-cases-for-some-Xinp.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0017-Add-REQUEST_FIXED_SIZE-testcases-to-test-misc.c.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0018-glx-Be-more-paranoid-about-variable-length-requests-.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0019-glx-Be-more-strict-about-rejecting-invalid-image-siz.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0020-glx-Additional-paranoia-in-__glXGetAnswerBuffer-__GL.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0021-glx-Fix-image-size-computation-for-EXT_texture_integ.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0022-glx-Add-safe_-add-mul-pad-v3-CVE-2014-8093-4-6.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0023-glx-Length-checking-for-GLXRender-requests-v2-CVE-20.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0024-glx-Integer-overflow-protection-for-non-generated-re.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0025-glx-Top-level-length-checking-for-swapped-VendorPriv.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0026-glx-Request-length-checks-for-SetClientInfoARB-CVE-2.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0027-glx-Length-checking-for-non-generated-vendor-private.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0028-glx-Length-checking-for-non-generated-single-request.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0029-glx-Fix-mask-truncation-in-__glXGetAnswerBuffer-CVE-.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0030-glx-Length-checking-for-RenderLarge-requests-v2-CVE-.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/0031-glx-Pass-remaining-request-length-into-varsize-v2-CV.patch create mode 100644 patches/source/xorg-server/patch/xorg-server/x11.startwithblackscreen.diff create mode 100644 patches/source/xorg-server/patch/xorg-server/xorg-server.CVE-2017-10971.diff create mode 100644 patches/source/xorg-server/patch/xorg-server/xorg-server.CVE-2017-10972.diff create mode 100644 patches/source/xorg-server/patch/xorg-server/xorg-server.CVE-2017-12176.diff create mode 100644 patches/source/xorg-server/patch/xorg-server/xorg-server.CVE-2017-12179_p1.diff create mode 100644 patches/source/xorg-server/patch/xorg-server/xorg-server.CVE-2017-12179_p2.diff create mode 100644 patches/source/xorg-server/patch/xorg-server/xorg-server.CVE-2017-12183.diff create mode 100644 patches/source/xorg-server/patch/xorg-server/xorg-server.CVE-2017-13723.diff (limited to 'patches/source/xorg-server/patch') diff --git a/patches/source/xorg-server/patch/xorg-server.patch b/patches/source/xorg-server/patch/xorg-server.patch new file mode 100644 index 000000000..1ce3d36ed --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server.patch @@ -0,0 +1,43 @@ +zcat $CWD/patch/xorg-server/x11.startwithblackscreen.diff.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +# 12/2014 security patches: +zcat $CWD/patch/xorg-server/0001-glx-check-return-from-__glXGetAnswerBuffer.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0001-unchecked-malloc-may-allow-unauthed-client-to-crash-.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0002-dix-integer-overflow-in-ProcPutImage-CVE-2014-8092-1.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0003-dix-integer-overflow-in-GetHosts-CVE-2014-8092-2-4.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0004-dix-integer-overflow-in-RegionSizeof-CVE-2014-8092-3.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0005-dix-integer-overflow-in-REQUEST_FIXED_SIZE-CVE-2014-.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0006-dri2-integer-overflow-in-ProcDRI2GetBuffers-CVE-2014.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0007-dbe-unvalidated-lengths-in-DbeSwapBuffers-calls-CVE-.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0008-Xi-unvalidated-lengths-in-Xinput-extension-CVE-2014-.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0009-xcmisc-unvalidated-length-in-SProcXCMiscGetXIDList-C.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0010-Xv-unvalidated-lengths-in-XVideo-extension-swapped-p.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0011-randr-unvalidated-lengths-in-RandR-extension-swapped.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0012-render-check-request-size-before-reading-it-CVE-2014.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0013-render-unvalidated-lengths-in-Render-extn.-swapped-p.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0014-xfixes-unvalidated-length-in-SProcXFixesSelectSelect.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0015-Add-request-length-checking-test-cases-for-some-Xinp.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0016-Add-request-length-checking-test-cases-for-some-Xinp.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0017-Add-REQUEST_FIXED_SIZE-testcases-to-test-misc.c.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0018-glx-Be-more-paranoid-about-variable-length-requests-.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0019-glx-Be-more-strict-about-rejecting-invalid-image-siz.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0020-glx-Additional-paranoia-in-__glXGetAnswerBuffer-__GL.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0021-glx-Fix-image-size-computation-for-EXT_texture_integ.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0022-glx-Add-safe_-add-mul-pad-v3-CVE-2014-8093-4-6.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0023-glx-Length-checking-for-GLXRender-requests-v2-CVE-20.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0024-glx-Integer-overflow-protection-for-non-generated-re.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0025-glx-Top-level-length-checking-for-swapped-VendorPriv.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0026-glx-Request-length-checks-for-SetClientInfoARB-CVE-2.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0027-glx-Length-checking-for-non-generated-vendor-private.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0028-glx-Length-checking-for-non-generated-single-request.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0029-glx-Fix-mask-truncation-in-__glXGetAnswerBuffer-CVE-.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0030-glx-Length-checking-for-RenderLarge-requests-v2-CVE-.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0031-glx-Pass-remaining-request-length-into-varsize-v2-CV.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0001-Missing-parens-in-REQUEST_FIXED_SIZE-macro-CVE-2014-.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/0002-dix-GetHosts-bounds-check-using-wrong-pointer-value-.patch.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/xorg-server.CVE-2017-10971.diff.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/xorg-server.CVE-2017-10972.diff.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/xorg-server.CVE-2017-13723.diff.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/xorg-server.CVE-2017-12176.diff.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/xorg-server.CVE-2017-12179_p1.diff.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/xorg-server.CVE-2017-12179_p2.diff.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } +zcat $CWD/patch/xorg-server/xorg-server.CVE-2017-12183.diff.gz | patch -p1 --verbose || { touch ${SLACK_X_BUILD_DIR}/${PKGNAME}.failed ; continue ; } diff --git a/patches/source/xorg-server/patch/xorg-server/0001-Missing-parens-in-REQUEST_FIXED_SIZE-macro-CVE-2014-.patch b/patches/source/xorg-server/patch/xorg-server/0001-Missing-parens-in-REQUEST_FIXED_SIZE-macro-CVE-2014-.patch new file mode 100644 index 000000000..ea5a3a30d --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/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/patches/source/xorg-server/patch/xorg-server/0001-glx-check-return-from-__glXGetAnswerBuffer.patch b/patches/source/xorg-server/patch/xorg-server/0001-glx-check-return-from-__glXGetAnswerBuffer.patch new file mode 100644 index 000000000..bbe3e85da --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0001-glx-check-return-from-__glXGetAnswerBuffer.patch @@ -0,0 +1,173 @@ +From 5e5f30641b07e40d9ba98210b92e38383594b328 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 | 18 ++++++++++++++++++ + glx/indirect_dispatch_swap.c | 18 ++++++++++++++++++ + 2 files changed, 36 insertions(+) + +diff --git a/glx/indirect_dispatch.c b/glx/indirect_dispatch.c +index 0a7623c..f290790 100644 +--- a/glx/indirect_dispatch.c ++++ b/glx/indirect_dispatch.c +@@ -2705,6 +2705,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 = + CALL_AreTexturesResident(GET_DISPATCH(), + (n, (const GLuint *) (pc + 4), +@@ -2731,6 +2734,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 = + CALL_AreTexturesResident(GET_DISPATCH(), + (n, (const GLuint *) (pc + 4), +@@ -2848,6 +2854,8 @@ __glXDisp_GenTextures(__GLXclientState * cl, GLbyte * pc) + GLuint *textures = + __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), + 4); ++ if (textures == NULL) ++ return BadAlloc; + CALL_GenTextures(GET_DISPATCH(), (n, textures)); + __glXSendReply(cl->client, textures, n, 4, GL_TRUE, 0); + error = Success; +@@ -2871,6 +2879,8 @@ __glXDisp_GenTexturesEXT(__GLXclientState * cl, GLbyte * pc) + GLuint *textures = + __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), + 4); ++ if (textures == NULL) ++ return BadAlloc; + CALL_GenTextures(GET_DISPATCH(), (n, textures)); + __glXSendReply(cl->client, textures, n, 4, GL_TRUE, 0); + error = Success; +@@ -4598,6 +4608,8 @@ __glXDisp_GenQueriesARB(__GLXclientState * cl, GLbyte * pc) + GLuint *ids = + __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), + 4); ++ if (ids == NULL) ++ return BadAlloc; + CALL_GenQueriesARB(GET_DISPATCH(), (n, ids)); + __glXSendReply(cl->client, ids, n, 4, GL_TRUE, 0); + error = Success; +@@ -4956,6 +4968,8 @@ __glXDisp_GenProgramsNV(__GLXclientState * cl, GLbyte * pc) + GLuint *programs = + __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), + 4); ++ if (programs == NULL) ++ return BadAlloc; + CALL_GenProgramsNV(GET_DISPATCH(), (n, programs)); + __glXSendReply(cl->client, programs, n, 4, GL_TRUE, 0); + error = Success; +@@ -5765,6 +5779,8 @@ __glXDisp_GenFramebuffersEXT(__GLXclientState * cl, GLbyte * pc) + GLuint *framebuffers = + __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), + 4); ++ if (framebuffers == NULL) ++ return BadAlloc; + CALL_GenFramebuffersEXT(GET_DISPATCH(), (n, framebuffers)); + __glXSendReply(cl->client, framebuffers, n, 4, GL_TRUE, 0); + error = Success; +@@ -5788,6 +5804,8 @@ __glXDisp_GenRenderbuffersEXT(__GLXclientState * cl, GLbyte * pc) + GLuint *renderbuffers = + __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), + 4); ++ if (renderbuffers == NULL) ++ return BadAlloc; + CALL_GenRenderbuffersEXT(GET_DISPATCH(), (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 80010b3..57b6c3c 100644 +--- a/glx/indirect_dispatch_swap.c ++++ b/glx/indirect_dispatch_swap.c +@@ -3076,6 +3076,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 = + CALL_AreTexturesResident(GET_DISPATCH(), + (n, +@@ -3105,6 +3108,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 = + CALL_AreTexturesResident(GET_DISPATCH(), + (n, +@@ -3233,6 +3239,8 @@ __glXDispSwap_GenTextures(__GLXclientState * cl, GLbyte * pc) + GLuint *textures = + __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), + 4); ++ if (textures == NULL) ++ return BadAlloc; + CALL_GenTextures(GET_DISPATCH(), (n, textures)); + (void) bswap_32_array((uint32_t *) textures, n); + __glXSendReplySwap(cl->client, textures, n, 4, GL_TRUE, 0); +@@ -3258,6 +3266,8 @@ __glXDispSwap_GenTexturesEXT(__GLXclientState * cl, GLbyte * pc) + GLuint *textures = + __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), + 4); ++ if (textures == NULL) ++ return BadAlloc; + CALL_GenTextures(GET_DISPATCH(), (n, textures)); + (void) bswap_32_array((uint32_t *) textures, n); + __glXSendReplySwap(cl->client, textures, n, 4, GL_TRUE, 0); +@@ -5259,6 +5269,8 @@ __glXDispSwap_GenQueriesARB(__GLXclientState * cl, GLbyte * pc) + GLuint *ids = + __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), + 4); ++ if (ids == NULL) ++ return BadAlloc; + CALL_GenQueriesARB(GET_DISPATCH(), (n, ids)); + (void) bswap_32_array((uint32_t *) ids, n); + __glXSendReplySwap(cl->client, ids, n, 4, GL_TRUE, 0); +@@ -5672,6 +5684,8 @@ __glXDispSwap_GenProgramsNV(__GLXclientState * cl, GLbyte * pc) + GLuint *programs = + __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), + 4); ++ if (programs == NULL) ++ return BadAlloc; + CALL_GenProgramsNV(GET_DISPATCH(), (n, programs)); + (void) bswap_32_array((uint32_t *) programs, n); + __glXSendReplySwap(cl->client, programs, n, 4, GL_TRUE, 0); +@@ -6610,6 +6624,8 @@ __glXDispSwap_GenFramebuffersEXT(__GLXclientState * cl, GLbyte * pc) + GLuint *framebuffers = + __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), + 4); ++ if (framebuffers == NULL) ++ return BadAlloc; + CALL_GenFramebuffersEXT(GET_DISPATCH(), (n, framebuffers)); + (void) bswap_32_array((uint32_t *) framebuffers, n); + __glXSendReplySwap(cl->client, framebuffers, n, 4, GL_TRUE, 0); +@@ -6635,6 +6651,8 @@ __glXDispSwap_GenRenderbuffersEXT(__GLXclientState * cl, GLbyte * pc) + GLuint *renderbuffers = + __glXGetAnswerBuffer(cl, n * 4, answerBuffer, sizeof(answerBuffer), + 4); ++ if (renderbuffers == NULL) ++ return BadAlloc; + CALL_GenRenderbuffersEXT(GET_DISPATCH(), (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/patches/source/xorg-server/patch/xorg-server/0001-unchecked-malloc-may-allow-unauthed-client-to-crash-.patch b/patches/source/xorg-server/patch/xorg-server/0001-unchecked-malloc-may-allow-unauthed-client-to-crash-.patch new file mode 100644 index 000000000..483bd74f9 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0001-unchecked-malloc-may-allow-unauthed-client-to-crash-.patch @@ -0,0 +1,41 @@ +From 2ecba31ddb5f4b953a0a811fec7fb7470b668f13 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Fri, 17 Jan 2014 18:54:03 -0800 +Subject: [PATCH 01/31] 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/patches/source/xorg-server/patch/xorg-server/0002-dix-GetHosts-bounds-check-using-wrong-pointer-value-.patch b/patches/source/xorg-server/patch/xorg-server/0002-dix-GetHosts-bounds-check-using-wrong-pointer-value-.patch new file mode 100644 index 000000000..c75c0a8f4 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/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/patches/source/xorg-server/patch/xorg-server/0002-dix-integer-overflow-in-ProcPutImage-CVE-2014-8092-1.patch b/patches/source/xorg-server/patch/xorg-server/0002-dix-integer-overflow-in-ProcPutImage-CVE-2014-8092-1.patch new file mode 100644 index 000000000..151a59aa5 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0002-dix-integer-overflow-in-ProcPutImage-CVE-2014-8092-1.patch @@ -0,0 +1,38 @@ +From 37dd6285cdfc2129a49f26d09addb27cb017ae61 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Wed, 22 Jan 2014 21:11:16 -0800 +Subject: [PATCH 02/31] 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 979ba48..8cb23d1 100644 +--- a/dix/dispatch.c ++++ b/dix/dispatch.c +@@ -1955,6 +1955,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/patches/source/xorg-server/patch/xorg-server/0003-dix-integer-overflow-in-GetHosts-CVE-2014-8092-2-4.patch b/patches/source/xorg-server/patch/xorg-server/0003-dix-integer-overflow-in-GetHosts-CVE-2014-8092-2-4.patch new file mode 100644 index 000000000..2034f285c --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0003-dix-integer-overflow-in-GetHosts-CVE-2014-8092-2-4.patch @@ -0,0 +1,50 @@ +From 7909f70e73f40113608fba3ddb657c05c3276da1 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Mon, 6 Jan 2014 23:30:14 -0800 +Subject: [PATCH 03/31] 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 88a44d9..e7d668a 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/patches/source/xorg-server/patch/xorg-server/0004-dix-integer-overflow-in-RegionSizeof-CVE-2014-8092-3.patch b/patches/source/xorg-server/patch/xorg-server/0004-dix-integer-overflow-in-RegionSizeof-CVE-2014-8092-3.patch new file mode 100644 index 000000000..8023f93eb --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0004-dix-integer-overflow-in-RegionSizeof-CVE-2014-8092-3.patch @@ -0,0 +1,129 @@ +From 8f82f69e9e4b76b01b9f5fe06d1ea86851d951c4 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Wed, 22 Jan 2014 22:37:15 -0800 +Subject: [PATCH 04/31] 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 737d2a8..76c4e29 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); \ +@@ -330,17 +330,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; +@@ -352,7 +355,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; +@@ -1297,6 +1301,7 @@ RegionFromRects(int nrects, xRectangle *prect, int ctype) + { + + RegionPtr pRgn; ++ size_t rgnSize; + RegDataPtr pData; + BoxPtr pBox; + int i; +@@ -1323,7 +1328,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 805257b..5006207 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/patches/source/xorg-server/patch/xorg-server/0005-dix-integer-overflow-in-REQUEST_FIXED_SIZE-CVE-2014-.patch b/patches/source/xorg-server/patch/xorg-server/0005-dix-integer-overflow-in-REQUEST_FIXED_SIZE-CVE-2014-.patch new file mode 100644 index 000000000..33c141cc1 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0005-dix-integer-overflow-in-REQUEST_FIXED_SIZE-CVE-2014-.patch @@ -0,0 +1,35 @@ +From b59388b04da1a27882ca19e0737a0903b2896740 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Wed, 22 Jan 2014 23:44:46 -0800 +Subject: [PATCH 05/31] 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/patches/source/xorg-server/patch/xorg-server/0006-dri2-integer-overflow-in-ProcDRI2GetBuffers-CVE-2014.patch b/patches/source/xorg-server/patch/xorg-server/0006-dri2-integer-overflow-in-ProcDRI2GetBuffers-CVE-2014.patch new file mode 100644 index 000000000..9688802e0 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0006-dri2-integer-overflow-in-ProcDRI2GetBuffers-CVE-2014.patch @@ -0,0 +1,36 @@ +From 26ef0a52797e8c3acd00c7a2bcb272abae73ca5e Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Wed, 22 Jan 2014 23:40:18 -0800 +Subject: [PATCH 06/31] 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 4ab0186..c3dbb2f 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/patches/source/xorg-server/patch/xorg-server/0007-dbe-unvalidated-lengths-in-DbeSwapBuffers-calls-CVE-.patch b/patches/source/xorg-server/patch/xorg-server/0007-dbe-unvalidated-lengths-in-DbeSwapBuffers-calls-CVE-.patch new file mode 100644 index 000000000..5d018b1c8 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0007-dbe-unvalidated-lengths-in-DbeSwapBuffers-calls-CVE-.patch @@ -0,0 +1,74 @@ +From ffd61dce4f10aba286ede4143c7763fda315fc49 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Wed, 22 Jan 2014 23:12:04 -0800 +Subject: [PATCH 07/31] 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 379feb1..f5a1940 100644 +--- a/dbe/dbe.c ++++ b/dbe/dbe.c +@@ -454,18 +454,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]; +@@ -956,13 +958,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/patches/source/xorg-server/patch/xorg-server/0008-Xi-unvalidated-lengths-in-Xinput-extension-CVE-2014-.patch b/patches/source/xorg-server/patch/xorg-server/0008-Xi-unvalidated-lengths-in-Xinput-extension-CVE-2014-.patch new file mode 100644 index 000000000..4e432d2ab --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0008-Xi-unvalidated-lengths-in-Xinput-extension-CVE-2014-.patch @@ -0,0 +1,552 @@ +From 078a38f9e9a83e171a266e5bc60a722a0d525528 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 26 Jan 2014 10:54:41 -0800 +Subject: [PATCH 08/31] 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 31d3a57..2dfc54c 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); +@@ -186,6 +186,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/patches/source/xorg-server/patch/xorg-server/0009-xcmisc-unvalidated-length-in-SProcXCMiscGetXIDList-C.patch b/patches/source/xorg-server/patch/xorg-server/0009-xcmisc-unvalidated-length-in-SProcXCMiscGetXIDList-C.patch new file mode 100644 index 000000000..a5acca741 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0009-xcmisc-unvalidated-length-in-SProcXCMiscGetXIDList-C.patch @@ -0,0 +1,28 @@ +From c097f07147409a4d6e60a7676fbc79c72307fd5f Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 26 Jan 2014 17:18:54 -0800 +Subject: [PATCH 09/31] 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/patches/source/xorg-server/patch/xorg-server/0010-Xv-unvalidated-lengths-in-XVideo-extension-swapped-p.patch b/patches/source/xorg-server/patch/xorg-server/0010-Xv-unvalidated-lengths-in-XVideo-extension-swapped-p.patch new file mode 100644 index 000000000..6e5111c68 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0010-Xv-unvalidated-lengths-in-XVideo-extension-swapped-p.patch @@ -0,0 +1,180 @@ +From 70127f3e8ee7cdf57e775720a642c0cbe8b8a140 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 26 Jan 2014 19:23:17 -0800 +Subject: [PATCH 10/31] 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 31b7783..6ac2366 100644 +--- a/Xext/xvdisp.c ++++ b/Xext/xvdisp.c +@@ -1218,6 +1218,7 @@ static int + SProcXvQueryExtension(ClientPtr client) + { + REQUEST(xvQueryExtensionReq); ++ REQUEST_SIZE_MATCH(xvQueryExtensionReq); + swaps(&stuff->length); + return XvProcVector[xv_QueryExtension] (client); + } +@@ -1226,6 +1227,7 @@ static int + SProcXvQueryAdaptors(ClientPtr client) + { + REQUEST(xvQueryAdaptorsReq); ++ REQUEST_SIZE_MATCH(xvQueryAdaptorsReq); + swaps(&stuff->length); + swapl(&stuff->window); + return XvProcVector[xv_QueryAdaptors] (client); +@@ -1235,6 +1237,7 @@ static int + SProcXvQueryEncodings(ClientPtr client) + { + REQUEST(xvQueryEncodingsReq); ++ REQUEST_SIZE_MATCH(xvQueryEncodingsReq); + swaps(&stuff->length); + swapl(&stuff->port); + return XvProcVector[xv_QueryEncodings] (client); +@@ -1244,6 +1247,7 @@ static int + SProcXvGrabPort(ClientPtr client) + { + REQUEST(xvGrabPortReq); ++ REQUEST_SIZE_MATCH(xvGrabPortReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->time); +@@ -1254,6 +1258,7 @@ static int + SProcXvUngrabPort(ClientPtr client) + { + REQUEST(xvUngrabPortReq); ++ REQUEST_SIZE_MATCH(xvUngrabPortReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->time); +@@ -1264,6 +1269,7 @@ static int + SProcXvPutVideo(ClientPtr client) + { + REQUEST(xvPutVideoReq); ++ REQUEST_SIZE_MATCH(xvPutVideoReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->drawable); +@@ -1283,6 +1289,7 @@ static int + SProcXvPutStill(ClientPtr client) + { + REQUEST(xvPutStillReq); ++ REQUEST_SIZE_MATCH(xvPutStillReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->drawable); +@@ -1302,6 +1309,7 @@ static int + SProcXvGetVideo(ClientPtr client) + { + REQUEST(xvGetVideoReq); ++ REQUEST_SIZE_MATCH(xvGetVideoReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->drawable); +@@ -1321,6 +1329,7 @@ static int + SProcXvGetStill(ClientPtr client) + { + REQUEST(xvGetStillReq); ++ REQUEST_SIZE_MATCH(xvGetStillReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->drawable); +@@ -1340,6 +1349,7 @@ static int + SProcXvPutImage(ClientPtr client) + { + REQUEST(xvPutImageReq); ++ REQUEST_AT_LEAST_SIZE(xvPutImageReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->drawable); +@@ -1363,6 +1373,7 @@ static int + SProcXvShmPutImage(ClientPtr client) + { + REQUEST(xvShmPutImageReq); ++ REQUEST_SIZE_MATCH(xvShmPutImageReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->drawable); +@@ -1390,6 +1401,7 @@ static int + SProcXvSelectVideoNotify(ClientPtr client) + { + REQUEST(xvSelectVideoNotifyReq); ++ REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq); + swaps(&stuff->length); + swapl(&stuff->drawable); + return XvProcVector[xv_SelectVideoNotify] (client); +@@ -1399,6 +1411,7 @@ static int + SProcXvSelectPortNotify(ClientPtr client) + { + REQUEST(xvSelectPortNotifyReq); ++ REQUEST_SIZE_MATCH(xvSelectPortNotifyReq); + swaps(&stuff->length); + swapl(&stuff->port); + return XvProcVector[xv_SelectPortNotify] (client); +@@ -1408,6 +1421,7 @@ static int + SProcXvStopVideo(ClientPtr client) + { + REQUEST(xvStopVideoReq); ++ REQUEST_SIZE_MATCH(xvStopVideoReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->drawable); +@@ -1418,6 +1432,7 @@ static int + SProcXvSetPortAttribute(ClientPtr client) + { + REQUEST(xvSetPortAttributeReq); ++ REQUEST_SIZE_MATCH(xvSetPortAttributeReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->attribute); +@@ -1429,6 +1444,7 @@ static int + SProcXvGetPortAttribute(ClientPtr client) + { + REQUEST(xvGetPortAttributeReq); ++ REQUEST_SIZE_MATCH(xvGetPortAttributeReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->attribute); +@@ -1439,6 +1455,7 @@ static int + SProcXvQueryBestSize(ClientPtr client) + { + REQUEST(xvQueryBestSizeReq); ++ REQUEST_SIZE_MATCH(xvQueryBestSizeReq); + swaps(&stuff->length); + swapl(&stuff->port); + swaps(&stuff->vid_w); +@@ -1452,6 +1469,7 @@ static int + SProcXvQueryPortAttributes(ClientPtr client) + { + REQUEST(xvQueryPortAttributesReq); ++ REQUEST_SIZE_MATCH(xvQueryPortAttributesReq); + swaps(&stuff->length); + swapl(&stuff->port); + return XvProcVector[xv_QueryPortAttributes] (client); +@@ -1461,6 +1479,7 @@ static int + SProcXvQueryImageAttributes(ClientPtr client) + { + REQUEST(xvQueryImageAttributesReq); ++ REQUEST_SIZE_MATCH(xvQueryImageAttributesReq); + swaps(&stuff->length); + swapl(&stuff->port); + swapl(&stuff->id); +@@ -1473,6 +1492,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/patches/source/xorg-server/patch/xorg-server/0011-randr-unvalidated-lengths-in-RandR-extension-swapped.patch b/patches/source/xorg-server/patch/xorg-server/0011-randr-unvalidated-lengths-in-RandR-extension-swapped.patch new file mode 100644 index 000000000..08f4f6000 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0011-randr-unvalidated-lengths-in-RandR-extension-swapped.patch @@ -0,0 +1,52 @@ +From 1e8e04d843fd97cfdbb3b83bd44de7493a3f7d83 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 26 Jan 2014 19:38:09 -0800 +Subject: [PATCH 11/31] 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/patches/source/xorg-server/patch/xorg-server/0012-render-check-request-size-before-reading-it-CVE-2014.patch b/patches/source/xorg-server/patch/xorg-server/0012-render-check-request-size-before-reading-it-CVE-2014.patch new file mode 100644 index 000000000..5984f54eb --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0012-render-check-request-size-before-reading-it-CVE-2014.patch @@ -0,0 +1,37 @@ +From ae07a61a956c1f0ec57502cc50fbab50c78fc675 Mon Sep 17 00:00:00 2001 +From: Julien Cristau +Date: Tue, 28 Oct 2014 10:30:04 +0100 +Subject: [PATCH 12/31] 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/patches/source/xorg-server/patch/xorg-server/0013-render-unvalidated-lengths-in-Render-extn.-swapped-p.patch b/patches/source/xorg-server/patch/xorg-server/0013-render-unvalidated-lengths-in-Render-extn.-swapped-p.patch new file mode 100644 index 000000000..71e487f7a --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0013-render-unvalidated-lengths-in-Render-extn.-swapped-p.patch @@ -0,0 +1,141 @@ +From 15b22df9df2006d752ce756e6529af47697d0bb8 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 26 Jan 2014 19:51:29 -0800 +Subject: [PATCH 13/31] 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/patches/source/xorg-server/patch/xorg-server/0014-xfixes-unvalidated-length-in-SProcXFixesSelectSelect.patch b/patches/source/xorg-server/patch/xorg-server/0014-xfixes-unvalidated-length-in-SProcXFixesSelectSelect.patch new file mode 100644 index 000000000..b7264a127 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0014-xfixes-unvalidated-length-in-SProcXFixesSelectSelect.patch @@ -0,0 +1,28 @@ +From a0564982917d62aaf1e12c76fb8f42b3f458dcc9 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 26 Jan 2014 20:02:20 -0800 +Subject: [PATCH 14/31] 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/patches/source/xorg-server/patch/xorg-server/0015-Add-request-length-checking-test-cases-for-some-Xinp.patch b/patches/source/xorg-server/patch/xorg-server/0015-Add-request-length-checking-test-cases-for-some-Xinp.patch new file mode 100644 index 000000000..db80930ba --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0015-Add-request-length-checking-test-cases-for-some-Xinp.patch @@ -0,0 +1,214 @@ +From cf226ef53fb26adf4860b52a713d47fd72ec8b26 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 9 Feb 2014 21:27:27 -0800 +Subject: [PATCH 15/31] 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 6d92bca..02830dd 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2341,6 +2341,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 6b96789..8cbcd9f 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 + 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/patches/source/xorg-server/patch/xorg-server/0016-Add-request-length-checking-test-cases-for-some-Xinp.patch b/patches/source/xorg-server/patch/xorg-server/0016-Add-request-length-checking-test-cases-for-some-Xinp.patch new file mode 100644 index 000000000..03740a169 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0016-Add-request-length-checking-test-cases-for-some-Xinp.patch @@ -0,0 +1,90 @@ +From 6aec61444897d54260df597785c9b215ac70a734 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 9 Feb 2014 21:28:05 -0800 +Subject: [PATCH 16/31] 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/patches/source/xorg-server/patch/xorg-server/0017-Add-REQUEST_FIXED_SIZE-testcases-to-test-misc.c.patch b/patches/source/xorg-server/patch/xorg-server/0017-Add-REQUEST_FIXED_SIZE-testcases-to-test-misc.c.patch new file mode 100644 index 000000000..1e9580e63 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0017-Add-REQUEST_FIXED_SIZE-testcases-to-test-misc.c.patch @@ -0,0 +1,75 @@ +From 04e6f8dff7e989f0181a1a8fb45c3bb918ee20d9 Mon Sep 17 00:00:00 2001 +From: Alan Coopersmith +Date: Sun, 9 Feb 2014 22:42:47 -0800 +Subject: [PATCH 17/31] 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/patches/source/xorg-server/patch/xorg-server/0018-glx-Be-more-paranoid-about-variable-length-requests-.patch b/patches/source/xorg-server/patch/xorg-server/0018-glx-Be-more-paranoid-about-variable-length-requests-.patch new file mode 100644 index 000000000..a39ebd1bb --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0018-glx-Be-more-paranoid-about-variable-length-requests-.patch @@ -0,0 +1,48 @@ +From 352687dcfcfc35fe3817c9baf1bc891401165605 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:36 -0500 +Subject: [PATCH 18/31] 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 c1f4e22..5b50785 100644 +--- a/glx/glxcmds.c ++++ b/glx/glxcmds.c +@@ -2008,7 +2008,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; +@@ -2125,7 +2125,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/patches/source/xorg-server/patch/xorg-server/0019-glx-Be-more-strict-about-rejecting-invalid-image-siz.patch b/patches/source/xorg-server/patch/xorg-server/0019-glx-Be-more-strict-about-rejecting-invalid-image-siz.patch new file mode 100644 index 000000000..b91c6d674 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0019-glx-Be-more-strict-about-rejecting-invalid-image-siz.patch @@ -0,0 +1,166 @@ +From 8580856661e09a5bdc9b9b44dd5304656d95666c Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:37 -0500 +Subject: [PATCH 19/31] 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 fb6868d..4137798 100644 +--- a/glx/singlepix.c ++++ b/glx/singlepix.c +@@ -69,7 +69,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; + + CALL_PixelStorei(GET_DISPATCH(), (GL_PACK_SWAP_BYTES, swapBytes)); + CALL_PixelStorei(GET_DISPATCH(), (GL_PACK_LSB_FIRST, lsbFirst)); +@@ -134,7 +134,7 @@ __glXDisp_GetTexImage(__GLXclientState * cl, GLbyte * pc) + compsize = + __glGetTexImage_size(target, level, format, type, width, height, depth); + if (compsize < 0) +- compsize = 0; ++ return BadLength; + + CALL_PixelStorei(GET_DISPATCH(), (GL_PACK_SWAP_BYTES, swapBytes)); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +@@ -232,9 +232,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); + +@@ -315,7 +315,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; + + CALL_PixelStorei(GET_DISPATCH(), (GL_PACK_SWAP_BYTES, swapBytes)); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +@@ -386,7 +386,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; + + CALL_PixelStorei(GET_DISPATCH(), (GL_PACK_SWAP_BYTES, swapBytes)); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +@@ -447,7 +447,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; + + CALL_PixelStorei(GET_DISPATCH(), (GL_PACK_SWAP_BYTES, swapBytes)); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +@@ -513,7 +513,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; + + CALL_PixelStorei(GET_DISPATCH(), (GL_PACK_SWAP_BYTES, swapBytes)); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +diff --git a/glx/singlepixswap.c b/glx/singlepixswap.c +index c777cea..16ea408 100644 +--- a/glx/singlepixswap.c ++++ b/glx/singlepixswap.c +@@ -79,7 +79,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; + + CALL_PixelStorei(GET_DISPATCH(), (GL_PACK_SWAP_BYTES, !swapBytes)); + CALL_PixelStorei(GET_DISPATCH(), (GL_PACK_LSB_FIRST, lsbFirst)); +@@ -155,7 +155,7 @@ __glXDispSwap_GetTexImage(__GLXclientState * cl, GLbyte * pc) + compsize = + __glGetTexImage_size(target, level, format, type, width, height, depth); + if (compsize < 0) +- compsize = 0; ++ return BadLength; + + CALL_PixelStorei(GET_DISPATCH(), (GL_PACK_SWAP_BYTES, !swapBytes)); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +@@ -267,9 +267,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); + +@@ -358,7 +358,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; + + CALL_PixelStorei(GET_DISPATCH(), (GL_PACK_SWAP_BYTES, !swapBytes)); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +@@ -437,7 +437,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; + + CALL_PixelStorei(GET_DISPATCH(), (GL_PACK_SWAP_BYTES, !swapBytes)); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +@@ -505,7 +505,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; + + CALL_PixelStorei(GET_DISPATCH(), (GL_PACK_SWAP_BYTES, !swapBytes)); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +@@ -577,7 +577,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; + + CALL_PixelStorei(GET_DISPATCH(), (GL_PACK_SWAP_BYTES, !swapBytes)); + __GLX_GET_ANSWER_BUFFER(answer, cl, compsize, 1); +-- +1.9.3 + diff --git a/patches/source/xorg-server/patch/xorg-server/0020-glx-Additional-paranoia-in-__glXGetAnswerBuffer-__GL.patch b/patches/source/xorg-server/patch/xorg-server/0020-glx-Additional-paranoia-in-__glXGetAnswerBuffer-__GL.patch new file mode 100644 index 000000000..d7ca0f388 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0020-glx-Additional-paranoia-in-__glXGetAnswerBuffer-__GL.patch @@ -0,0 +1,60 @@ +From 9cf40ac3793ab273d9c6c94fca93daf17ebb8881 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:38 -0500 +Subject: [PATCH 20/31] 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 a30b1f8..7431d43 100644 +--- a/glx/indirect_util.c ++++ b/glx/indirect_util.c +@@ -81,9 +81,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/patches/source/xorg-server/patch/xorg-server/0021-glx-Fix-image-size-computation-for-EXT_texture_integ.patch b/patches/source/xorg-server/patch/xorg-server/0021-glx-Fix-image-size-computation-for-EXT_texture_integ.patch new file mode 100644 index 000000000..bfc8d4638 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0021-glx-Fix-image-size-computation-for-EXT_texture_integ.patch @@ -0,0 +1,60 @@ +From bf0ab1bee4d590fbfaa2fd4e56857b019898e21a Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:39 -0500 +Subject: [PATCH 21/31] 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/patches/source/xorg-server/patch/xorg-server/0022-glx-Add-safe_-add-mul-pad-v3-CVE-2014-8093-4-6.patch b/patches/source/xorg-server/patch/xorg-server/0022-glx-Add-safe_-add-mul-pad-v3-CVE-2014-8093-4-6.patch new file mode 100644 index 000000000..baeba4781 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0022-glx-Add-safe_-add-mul-pad-v3-CVE-2014-8093-4-6.patch @@ -0,0 +1,83 @@ +From 8a5685c7abbcd5185974bb29d94420bf348960a2 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:40 -0500 +Subject: [PATCH 22/31] 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 1021aec..1bc398b 100644 +--- a/glx/glxserver.h ++++ b/glx/glxserver.h +@@ -214,6 +214,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/patches/source/xorg-server/patch/xorg-server/0023-glx-Length-checking-for-GLXRender-requests-v2-CVE-20.patch b/patches/source/xorg-server/patch/xorg-server/0023-glx-Length-checking-for-GLXRender-requests-v2-CVE-20.patch new file mode 100644 index 000000000..96de637aa --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0023-glx-Length-checking-for-GLXRender-requests-v2-CVE-20.patch @@ -0,0 +1,76 @@ +From bce43e2e287096be4c737105fa12459ff2e052b2 Mon Sep 17 00:00:00 2001 +From: Julien Cristau +Date: Mon, 10 Nov 2014 12:13:41 -0500 +Subject: [PATCH 23/31] 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 5b50785..969bf01 100644 +--- a/glx/glxcmds.c ++++ b/glx/glxcmds.c +@@ -1971,7 +1971,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; + +@@ -1990,6 +1990,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. + */ +@@ -2003,6 +2006,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, +@@ -2010,17 +2017,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/patches/source/xorg-server/patch/xorg-server/0024-glx-Integer-overflow-protection-for-non-generated-re.patch b/patches/source/xorg-server/patch/xorg-server/0024-glx-Integer-overflow-protection-for-non-generated-re.patch new file mode 100644 index 000000000..d8dfa82a2 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0024-glx-Integer-overflow-protection-for-non-generated-re.patch @@ -0,0 +1,226 @@ +From 47ec44325195ae0655aa12310094799c595a0da2 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:42 -0500 +Subject: [PATCH 24/31] 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/patches/source/xorg-server/patch/xorg-server/0025-glx-Top-level-length-checking-for-swapped-VendorPriv.patch b/patches/source/xorg-server/patch/xorg-server/0025-glx-Top-level-length-checking-for-swapped-VendorPriv.patch new file mode 100644 index 000000000..202dcaf14 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0025-glx-Top-level-length-checking-for-swapped-VendorPriv.patch @@ -0,0 +1,52 @@ +From 4b8686ae33f68a1db609654d1b4ff9b20dcafd8a Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:44 -0500 +Subject: [PATCH 25/31] 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 43f88d3..6de14d2 100644 +--- a/glx/glxcmdsswap.c ++++ b/glx/glxcmdsswap.c +@@ -962,11 +962,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); +@@ -989,11 +991,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/patches/source/xorg-server/patch/xorg-server/0026-glx-Request-length-checks-for-SetClientInfoARB-CVE-2.patch b/patches/source/xorg-server/patch/xorg-server/0026-glx-Request-length-checks-for-SetClientInfoARB-CVE-2.patch new file mode 100644 index 000000000..29c189614 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0026-glx-Request-length-checks-for-SetClientInfoARB-CVE-2.patch @@ -0,0 +1,75 @@ +From 84f275b466fa69d14d91b2ad1353d05f642d3808 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:45 -0500 +Subject: [PATCH 26/31] 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/patches/source/xorg-server/patch/xorg-server/0027-glx-Length-checking-for-non-generated-vendor-private.patch b/patches/source/xorg-server/patch/xorg-server/0027-glx-Length-checking-for-non-generated-vendor-private.patch new file mode 100644 index 000000000..f748fa89c --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0027-glx-Length-checking-for-non-generated-vendor-private.patch @@ -0,0 +1,46 @@ +From dd7ac54c7ed15cdc63626abb534c0e1434f37dec Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:46 -0500 +Subject: [PATCH 27/31] 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 0114d73..efd0027 100644 +--- a/glx/indirect_program.c ++++ b/glx/indirect_program.c +@@ -69,6 +69,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 7533d26..90636f1 100644 +--- a/glx/swap_interval.c ++++ b/glx/swap_interval.c +@@ -50,6 +50,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/patches/source/xorg-server/patch/xorg-server/0028-glx-Length-checking-for-non-generated-single-request.patch b/patches/source/xorg-server/patch/xorg-server/0028-glx-Length-checking-for-non-generated-single-request.patch new file mode 100644 index 000000000..cacde310a --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0028-glx-Length-checking-for-non-generated-single-request.patch @@ -0,0 +1,565 @@ +From 48330fbc7cdc7a3de1a4eb1c0af297352075bd8f Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:47 -0500 +Subject: [PATCH 28/31] 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 5c2d06b..fe6c6fa 100644 +--- a/glx/indirect_texture_compression.c ++++ b/glx/indirect_texture_compression.c +@@ -47,6 +47,8 @@ __glXDisp_GetCompressedTexImageARB(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); +@@ -93,6 +95,8 @@ __glXDispSwap_GetCompressedTexImageARB(struct __GLXclientStateRec *cl, + __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 9597d29..d735149 100644 +--- a/glx/single2.c ++++ b/glx/single2.c +@@ -49,11 +49,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; +@@ -80,10 +83,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; +@@ -108,7 +114,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; +@@ -116,6 +122,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; +@@ -192,7 +200,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, +@@ -211,9 +218,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; +@@ -227,10 +237,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; +@@ -321,7 +333,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; +@@ -331,6 +343,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. + */ +@@ -347,7 +361,6 @@ DoGetString(__GLXclientState * cl, GLbyte * pc, GLboolean need_swap) + pc += __GLX_SINGLE_HDR_SIZE; + name = *(GLenum *) (pc + 0); + string = (const char *) CALL_GetString(GET_DISPATCH(), (name)); +- client = cl->client; + + if (string == NULL) + string = ""; +diff --git a/glx/single2swap.c b/glx/single2swap.c +index 1ca5328..907dfdf 100644 +--- a/glx/single2swap.c ++++ b/glx/single2swap.c +@@ -45,6 +45,7 @@ + int + __glXDispSwap_FeedbackBuffer(__GLXclientState * cl, GLbyte * pc) + { ++ ClientPtr client = cl->client; + GLsizei size; + GLenum type; + +@@ -52,6 +53,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) { +@@ -81,12 +84,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) { +@@ -113,7 +119,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; +@@ -124,6 +130,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) { +@@ -204,7 +212,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, +@@ -228,11 +235,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) { +@@ -247,12 +257,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) { +@@ -264,7 +276,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 4137798..4771fb4 100644 +--- a/glx/singlepix.c ++++ b/glx/singlepix.c +@@ -55,6 +55,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; +@@ -107,6 +109,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; +@@ -169,6 +173,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; +@@ -231,15 +237,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); + + CALL_PixelStorei(GET_DISPATCH(), (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(); + CALL_GetSeparableFilter(GET_DISPATCH(), (*(GLenum *) (pc + 0), + *(GLenum *) (pc + 4), +@@ -265,7 +269,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); + } + +@@ -273,7 +278,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); + } + +@@ -343,7 +349,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); + } + +@@ -351,7 +358,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); + } + +@@ -411,7 +419,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); + } + +@@ -419,7 +428,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); + } + +@@ -471,7 +481,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); + } + +@@ -479,7 +490,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); + } + +@@ -540,7 +552,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); + } + +@@ -548,6 +561,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 16ea408..7f007b5 100644 +--- a/glx/singlepixswap.c ++++ b/glx/singlepixswap.c +@@ -57,6 +57,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) { +@@ -122,6 +124,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) { +@@ -197,6 +201,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) { +@@ -266,15 +272,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); + + CALL_PixelStorei(GET_DISPATCH(), (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(); + CALL_GetSeparableFilter(GET_DISPATCH(), (*(GLenum *) (pc + 0), + *(GLenum *) (pc + 4), +@@ -302,7 +306,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); + } + +@@ -310,7 +316,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); + } + +@@ -388,7 +396,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); + } + +@@ -396,7 +406,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); + } + +@@ -463,7 +475,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); + } + +@@ -471,7 +485,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); + } + +@@ -529,7 +545,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); + } + +@@ -537,7 +555,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); + } + +@@ -605,7 +625,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); + } + +@@ -613,6 +635,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/patches/source/xorg-server/patch/xorg-server/0029-glx-Fix-mask-truncation-in-__glXGetAnswerBuffer-CVE-.patch b/patches/source/xorg-server/patch/xorg-server/0029-glx-Fix-mask-truncation-in-__glXGetAnswerBuffer-CVE-.patch new file mode 100644 index 000000000..5a6cff9b4 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0029-glx-Fix-mask-truncation-in-__glXGetAnswerBuffer-CVE-.patch @@ -0,0 +1,35 @@ +From 3e9dd82063cc50d649517ee21ce68cfe4b98a1f6 Mon Sep 17 00:00:00 2001 +From: Robert Morell +Date: Wed, 12 Nov 2014 18:51:43 -0800 +Subject: [PATCH 29/31] 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 7431d43..5914f5b 100644 +--- a/glx/indirect_util.c ++++ b/glx/indirect_util.c +@@ -78,7 +78,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/patches/source/xorg-server/patch/xorg-server/0030-glx-Length-checking-for-RenderLarge-requests-v2-CVE-.patch b/patches/source/xorg-server/patch/xorg-server/0030-glx-Length-checking-for-RenderLarge-requests-v2-CVE-.patch new file mode 100644 index 000000000..6542a5135 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0030-glx-Length-checking-for-RenderLarge-requests-v2-CVE-.patch @@ -0,0 +1,159 @@ +From a2af6cb8a699966e13c0bbcafc41da2f0e814b86 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:43 -0500 +Subject: [PATCH 30/31] 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 969bf01..4715328 100644 +--- a/glx/glxcmds.c ++++ b/glx/glxcmds.c +@@ -2055,6 +2055,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); +@@ -2070,12 +2072,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); +@@ -2085,7 +2089,7 @@ __glXDisp_RenderLarge(__GLXclientState * cl, GLbyte * pc) + + if (cl->largeCmdRequestsSoFar == 0) { + __GLXrenderSizeData entry; +- int extra; ++ int extra = 0; + size_t cmdlen; + int err; + +@@ -2098,13 +2102,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. +@@ -2126,17 +2134,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. + */ +@@ -2166,6 +2170,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. +@@ -2184,11 +2189,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++; +@@ -2200,17 +2212,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/patches/source/xorg-server/patch/xorg-server/0031-glx-Pass-remaining-request-length-into-varsize-v2-CV.patch b/patches/source/xorg-server/patch/xorg-server/0031-glx-Pass-remaining-request-length-into-varsize-v2-CV.patch new file mode 100644 index 000000000..e9a785f66 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/0031-glx-Pass-remaining-request-length-into-varsize-v2-CV.patch @@ -0,0 +1,935 @@ +From 37a79fa54d3ddd1d4f6c9c0362dbe9616151ec9c Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 10 Nov 2014 12:13:48 -0500 +Subject: [PATCH 31/31] 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 | 154 ++++++++++++++++++++++++------------------------- + glx/indirect_reqsize.h | 148 +++++++++++++++++++++++------------------------ + glx/rensize.c | 27 ++++++--- + 5 files changed, 174 insertions(+), 164 deletions(-) + +diff --git a/glx/glxcmds.c b/glx/glxcmds.c +index 4715328..59b1de5 100644 +--- a/glx/glxcmds.c ++++ b/glx/glxcmds.c +@@ -2013,7 +2013,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; + } +@@ -2090,6 +2091,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; + +@@ -2130,7 +2132,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 1bc398b..9e660a5 100644 +--- a/glx/glxserver.h ++++ b/glx/glxserver.h +@@ -163,7 +163,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 86ea970..ce58214 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 +-__glXCompressedTexImage1DARBReqSize(const GLbyte * pc, Bool swap) ++__glXCompressedTexImage1DARBReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei imageSize = *(GLsizei *) (pc + 20); + +@@ -621,11 +619,11 @@ __glXCompressedTexImage1DARBReqSize(const GLbyte * pc, Bool swap) + imageSize = bswap_32(imageSize); + } + +- return __GLX_PAD(imageSize); ++ return safe_pad(imageSize); + } + + int +-__glXCompressedTexImage2DARBReqSize(const GLbyte * pc, Bool swap) ++__glXCompressedTexImage2DARBReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei imageSize = *(GLsizei *) (pc + 24); + +@@ -633,11 +631,11 @@ __glXCompressedTexImage2DARBReqSize(const GLbyte * pc, Bool swap) + imageSize = bswap_32(imageSize); + } + +- return __GLX_PAD(imageSize); ++ return safe_pad(imageSize); + } + + int +-__glXCompressedTexImage3DARBReqSize(const GLbyte * pc, Bool swap) ++__glXCompressedTexImage3DARBReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei imageSize = *(GLsizei *) (pc + 28); + +@@ -645,11 +643,11 @@ __glXCompressedTexImage3DARBReqSize(const GLbyte * pc, Bool swap) + imageSize = bswap_32(imageSize); + } + +- return __GLX_PAD(imageSize); ++ return safe_pad(imageSize); + } + + int +-__glXCompressedTexSubImage3DARBReqSize(const GLbyte * pc, Bool swap) ++__glXCompressedTexSubImage3DARBReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei imageSize = *(GLsizei *) (pc + 36); + +@@ -657,11 +655,11 @@ __glXCompressedTexSubImage3DARBReqSize(const GLbyte * pc, Bool swap) + imageSize = bswap_32(imageSize); + } + +- return __GLX_PAD(imageSize); ++ return safe_pad(imageSize); + } + + int +-__glXProgramStringARBReqSize(const GLbyte * pc, Bool swap) ++__glXProgramStringARBReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei len = *(GLsizei *) (pc + 8); + +@@ -669,11 +667,11 @@ __glXProgramStringARBReqSize(const GLbyte * pc, Bool swap) + len = bswap_32(len); + } + +- return __GLX_PAD(len); ++ return safe_pad(len); + } + + int +-__glXDrawBuffersARBReqSize(const GLbyte * pc, Bool swap) ++__glXDrawBuffersARBReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei n = *(GLsizei *) (pc + 0); + +@@ -681,11 +679,11 @@ __glXDrawBuffersARBReqSize(const GLbyte * pc, Bool swap) + n = bswap_32(n); + } + +- return __GLX_PAD((n * 4)); ++ return safe_pad(safe_mul(n, 4)); + } + + int +-__glXPointParameterfvEXTReqSize(const GLbyte * pc, Bool swap) ++__glXPointParameterfvEXTReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLenum pname = *(GLenum *) (pc + 0); + GLsizei compsize; +@@ -695,11 +693,11 @@ __glXPointParameterfvEXTReqSize(const GLbyte * pc, Bool swap) + } + + compsize = __glPointParameterfvEXT_size(pname); +- return __GLX_PAD((compsize * 4)); ++ return safe_pad(safe_mul(compsize, 4)); + } + + int +-__glXProgramParameters4dvNVReqSize(const GLbyte * pc, Bool swap) ++__glXProgramParameters4dvNVReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei num = *(GLsizei *) (pc + 8); + +@@ -707,11 +705,11 @@ __glXProgramParameters4dvNVReqSize(const GLbyte * pc, Bool swap) + num = bswap_32(num); + } + +- return __GLX_PAD((num * 32)); ++ return safe_pad(safe_mul(num, 32)); + } + + int +-__glXProgramParameters4fvNVReqSize(const GLbyte * pc, Bool swap) ++__glXProgramParameters4fvNVReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei num = *(GLsizei *) (pc + 8); + +@@ -719,11 +717,11 @@ __glXProgramParameters4fvNVReqSize(const GLbyte * pc, Bool swap) + num = bswap_32(num); + } + +- return __GLX_PAD((num * 16)); ++ return safe_pad(safe_mul(num, 16)); + } + + int +-__glXVertexAttribs1dvNVReqSize(const GLbyte * pc, Bool swap) ++__glXVertexAttribs1dvNVReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei n = *(GLsizei *) (pc + 4); + +@@ -731,11 +729,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); + +@@ -743,11 +741,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); + +@@ -755,11 +753,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); + +@@ -767,11 +765,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); + +@@ -779,11 +777,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); + +@@ -791,11 +789,11 @@ __glXVertexAttribs4dvNVReqSize(const GLbyte * pc, Bool swap) + n = bswap_32(n); + } + +- return __GLX_PAD((n * 32)); ++ return safe_pad(safe_mul(n, 32)); + } + + int +-__glXProgramNamedParameter4fvNVReqSize(const GLbyte * pc, Bool swap) ++__glXProgramNamedParameter4fvNVReqSize(const GLbyte * pc, Bool swap, int reqlen) + { + GLsizei len = *(GLsizei *) (pc + 4); + +@@ -803,7 +801,7 @@ __glXProgramNamedParameter4fvNVReqSize(const GLbyte * pc, Bool swap) + len = bswap_32(len); + } + +- return __GLX_PAD(len); ++ return safe_pad(len); + } + + ALIAS(Fogiv, Fogfv) +diff --git a/glx/indirect_reqsize.h b/glx/indirect_reqsize.h +index d2c1da7..22e1350 100644 +--- a/glx/indirect_reqsize.h ++++ b/glx/indirect_reqsize.h +@@ -36,128 +36,128 @@ + #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 __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); ++ Bool swap, int reqlen); + 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); ++ 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 __glXCompressedTexImage1DARBReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXCompressedTexImage2DARBReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXCompressedTexImage3DARBReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXCompressedTexSubImage1DARBReqSize(const GLbyte * +- pc, Bool swap); ++ pc, Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXCompressedTexSubImage2DARBReqSize(const GLbyte * +- pc, Bool swap); ++ pc, Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXCompressedTexSubImage3DARBReqSize(const GLbyte * +- pc, Bool swap); ++ 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 __glXDrawBuffersARBReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXPointParameterfvEXTReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXLoadProgramNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXProgramParameters4dvNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXProgramParameters4fvNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXRequestResidentProgramsNVReqSize(const GLbyte * +- pc, Bool swap); ++ pc, 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); + extern PURE _X_HIDDEN int __glXPointParameterivNVReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXProgramNamedParameter4dvNVReqSize(const GLbyte * +- pc, Bool swap); ++ pc, Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXProgramNamedParameter4fvNVReqSize(const GLbyte * +- pc, Bool swap); ++ pc, Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXDeleteFramebuffersEXTReqSize(const GLbyte * pc, +- Bool swap); ++ Bool swap, int reqlen); + extern PURE _X_HIDDEN int __glXDeleteRenderbuffersEXTReqSize(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/patches/source/xorg-server/patch/xorg-server/x11.startwithblackscreen.diff b/patches/source/xorg-server/patch/xorg-server/x11.startwithblackscreen.diff new file mode 100644 index 000000000..8c0e3b546 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/x11.startwithblackscreen.diff @@ -0,0 +1,14 @@ +diff -Nur xorg-server-1.12.1.orig/dix/window.c xorg-server-1.12.1/dix/window.c +--- xorg-server-1.12.1.orig/dix/window.c 2012-03-29 21:57:25.000000000 -0500 ++++ xorg-server-1.12.1/dix/window.c 2012-04-13 22:01:24.456073603 -0500 +@@ -145,8 +145,8 @@ + + Bool bgNoneRoot = FALSE; + +-static unsigned char _back_lsb[4] = { 0x88, 0x22, 0x44, 0x11 }; +-static unsigned char _back_msb[4] = { 0x11, 0x44, 0x22, 0x88 }; ++static unsigned char _back_lsb[4] = { 0x00, 0x00, 0x00, 0x00 }; ++static unsigned char _back_msb[4] = { 0x00, 0x00, 0x00, 0x00 }; + + static Bool WindowParentHasDeviceCursor(WindowPtr pWin, + DeviceIntPtr pDev, CursorPtr pCurs); diff --git a/patches/source/xorg-server/patch/xorg-server/xorg-server.CVE-2017-10971.diff b/patches/source/xorg-server/patch/xorg-server/xorg-server.CVE-2017-10971.diff new file mode 100644 index 000000000..00ed28ac3 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/xorg-server.CVE-2017-10971.diff @@ -0,0 +1,40 @@ +From ba336b24052122b136486961c82deac76bbde455 Mon Sep 17 00:00:00 2001 +From: Michal Srb +Date: Wed, 24 May 2017 15:54:42 +0300 +Subject: Xi: Do not try to swap GenericEvent. + +The SProcXSendExtensionEvent must not attempt to swap GenericEvent because +it is assuming that the event has fixed size and gives the swapping function +xEvent-sized buffer. + +A GenericEvent would be later rejected by ProcXSendExtensionEvent anyway. + +Signed-off-by: Michal Srb +Reviewed-by: Peter Hutterer +Signed-off-by: Peter Hutterer + +diff --git a/Xi/sendexev.c b/Xi/sendexev.c +index 5e63bfc..5c2e0fc 100644 +--- a/Xi/sendexev.c ++++ b/Xi/sendexev.c +@@ -95,9 +95,17 @@ SProcXSendExtensionEvent(ClientPtr client) + + eventP = (xEvent *) &stuff[1]; + for (i = 0; i < stuff->num_events; i++, eventP++) { ++ if (eventP->u.u.type == GenericEvent) { ++ client->errorValue = eventP->u.u.type; ++ return BadValue; ++ } ++ + proc = EventSwapVector[eventP->u.u.type & 0177]; +- if (proc == NotImplemented) /* no swapping proc; invalid event type? */ ++ /* no swapping proc; invalid event type? */ ++ if (proc == NotImplemented) { ++ client->errorValue = eventP->u.u.type; + return BadValue; ++ } + (*proc) (eventP, &eventT); + *eventP = eventT; + } +-- +cgit v0.10.2 diff --git a/patches/source/xorg-server/patch/xorg-server/xorg-server.CVE-2017-10972.diff b/patches/source/xorg-server/patch/xorg-server/xorg-server.CVE-2017-10972.diff new file mode 100644 index 000000000..edddc8d66 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/xorg-server.CVE-2017-10972.diff @@ -0,0 +1,36 @@ +From 05442de962d3dc624f79fc1a00eca3ffc5489ced Mon Sep 17 00:00:00 2001 +From: Michal Srb +Date: Wed, 24 May 2017 15:54:39 +0300 +Subject: Xi: Zero target buffer in SProcXSendExtensionEvent. + +Make sure that the xEvent eventT is initialized with zeros, the same way as +in SProcSendEvent. + +Some event swapping functions do not overwrite all 32 bytes of xEvent +structure, for example XSecurityAuthorizationRevoked. Two cooperating +clients, one swapped and the other not, can send +XSecurityAuthorizationRevoked event to each other to retrieve old stack data +from X server. This can be potentialy misused to go around ASLR or +stack-protector. + +Signed-off-by: Michal Srb +Reviewed-by: Peter Hutterer +Signed-off-by: Peter Hutterer + +diff --git a/Xi/sendexev.c b/Xi/sendexev.c +index 11d8202..1cf118a 100644 +--- a/Xi/sendexev.c ++++ b/Xi/sendexev.c +@@ -78,7 +78,7 @@ SProcXSendExtensionEvent(ClientPtr client) + { + CARD32 *p; + int i; +- xEvent eventT; ++ xEvent eventT = { .u.u.type = 0 }; + xEvent *eventP; + EventSwapPtr proc; + +-- +cgit v0.10.2 + + diff --git a/patches/source/xorg-server/patch/xorg-server/xorg-server.CVE-2017-12176.diff b/patches/source/xorg-server/patch/xorg-server/xorg-server.CVE-2017-12176.diff new file mode 100644 index 000000000..9caf31247 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/xorg-server.CVE-2017-12176.diff @@ -0,0 +1,31 @@ +From b747da5e25be944337a9cd1415506fc06b70aa81 Mon Sep 17 00:00:00 2001 +From: Nathan Kidd +Date: Fri, 9 Jan 2015 10:15:46 -0500 +Subject: Unvalidated extra length in ProcEstablishConnection (CVE-2017-12176) + +Reviewed-by: Julien Cristau +Signed-off-by: Nathan Kidd +Signed-off-by: Julien Cristau + +diff --git a/dix/dispatch.c b/dix/dispatch.c +index 8b371b6..176c7a0 100644 +--- a/dix/dispatch.c ++++ b/dix/dispatch.c +@@ -3702,7 +3702,12 @@ ProcEstablishConnection(ClientPtr client) + prefix = (xConnClientPrefix *) ((char *) stuff + sz_xReq); + auth_proto = (char *) prefix + sz_xConnClientPrefix; + auth_string = auth_proto + pad_to_int32(prefix->nbytesAuthProto); +- if ((prefix->majorVersion != X_PROTOCOL) || ++ ++ if ((client->req_len << 2) != sz_xReq + sz_xConnClientPrefix + ++ pad_to_int32(prefix->nbytesAuthProto) + ++ pad_to_int32(prefix->nbytesAuthString)) ++ reason = "Bad length"; ++ else if ((prefix->majorVersion != X_PROTOCOL) || + (prefix->minorVersion != X_PROTOCOL_REVISION)) + reason = "Protocol version mismatch"; + else +-- +cgit v0.10.2 + + diff --git a/patches/source/xorg-server/patch/xorg-server/xorg-server.CVE-2017-12179_p1.diff b/patches/source/xorg-server/patch/xorg-server/xorg-server.CVE-2017-12179_p1.diff new file mode 100644 index 000000000..0b3734642 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/xorg-server.CVE-2017-12179_p1.diff @@ -0,0 +1,42 @@ +From 211e05ac85a294ef361b9f80d689047fa52b9076 Mon Sep 17 00:00:00 2001 +From: Michal Srb +Date: Fri, 7 Jul 2017 17:21:46 +0200 +Subject: Xi: Test exact size of XIBarrierReleasePointer + +Otherwise a client can send any value of num_barriers and cause reading or swapping of values on heap behind the receive buffer. + +Signed-off-by: Peter Hutterer + +diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c +index af1562e..d82ecb6 100644 +--- a/Xi/xibarriers.c ++++ b/Xi/xibarriers.c +@@ -830,10 +830,13 @@ SProcXIBarrierReleasePointer(ClientPtr client) + REQUEST(xXIBarrierReleasePointerReq); + int i; + +- info = (xXIBarrierReleasePointerInfo*) &stuff[1]; +- + swaps(&stuff->length); ++ REQUEST_AT_LEAST_SIZE(xXIBarrierReleasePointerReq); ++ + swapl(&stuff->num_barriers); ++ REQUEST_FIXED_SIZE(xXIBarrierReleasePointerReq, stuff->num_barriers * sizeof(xXIBarrierReleasePointerInfo)); ++ ++ info = (xXIBarrierReleasePointerInfo*) &stuff[1]; + for (i = 0; i < stuff->num_barriers; i++, info++) { + swaps(&info->deviceid); + swapl(&info->barrier); +@@ -853,7 +856,7 @@ ProcXIBarrierReleasePointer(ClientPtr client) + xXIBarrierReleasePointerInfo *info; + + REQUEST(xXIBarrierReleasePointerReq); +- REQUEST_AT_LEAST_SIZE(xXIBarrierReleasePointerReq); ++ REQUEST_FIXED_SIZE(xXIBarrierReleasePointerReq, stuff->num_barriers * sizeof(xXIBarrierReleasePointerInfo)); + + info = (xXIBarrierReleasePointerInfo*) &stuff[1]; + for (i = 0; i < stuff->num_barriers; i++, info++) { +-- +cgit v0.10.2 + + diff --git a/patches/source/xorg-server/patch/xorg-server/xorg-server.CVE-2017-12179_p2.diff b/patches/source/xorg-server/patch/xorg-server/xorg-server.CVE-2017-12179_p2.diff new file mode 100644 index 000000000..346756033 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/xorg-server.CVE-2017-12179_p2.diff @@ -0,0 +1,46 @@ +From d088e3c1286b548a58e62afdc70bb40981cdb9e8 Mon Sep 17 00:00:00 2001 +From: Nathan Kidd +Date: Fri, 9 Jan 2015 10:04:41 -0500 +Subject: Xi: integer overflow and unvalidated length in + (S)ProcXIBarrierReleasePointer + +[jcristau: originally this patch fixed the same issue as commit + 211e05ac85 "Xi: Test exact size of XIBarrierReleasePointer", with the + addition of these checks] + +This addresses CVE-2017-12179 + +Reviewed-by: Alan Coopersmith +Reviewed-by: Jeremy Huddleston Sequoia +Reviewed-by: Julien Cristau +Signed-off-by: Jeremy Huddleston Sequoia +Signed-off-by: Nathan Kidd +Signed-off-by: Julien Cristau + +diff --git a/Xi/xibarriers.c b/Xi/xibarriers.c +index d82ecb6..d0be701 100644 +--- a/Xi/xibarriers.c ++++ b/Xi/xibarriers.c +@@ -834,6 +834,8 @@ SProcXIBarrierReleasePointer(ClientPtr client) + REQUEST_AT_LEAST_SIZE(xXIBarrierReleasePointerReq); + + swapl(&stuff->num_barriers); ++ if (stuff->num_barriers > UINT32_MAX / sizeof(xXIBarrierReleasePointerInfo)) ++ return BadLength; + REQUEST_FIXED_SIZE(xXIBarrierReleasePointerReq, stuff->num_barriers * sizeof(xXIBarrierReleasePointerInfo)); + + info = (xXIBarrierReleasePointerInfo*) &stuff[1]; +@@ -856,6 +858,9 @@ ProcXIBarrierReleasePointer(ClientPtr client) + xXIBarrierReleasePointerInfo *info; + + REQUEST(xXIBarrierReleasePointerReq); ++ REQUEST_AT_LEAST_SIZE(xXIBarrierReleasePointerReq); ++ if (stuff->num_barriers > UINT32_MAX / sizeof(xXIBarrierReleasePointerInfo)) ++ return BadLength; + REQUEST_FIXED_SIZE(xXIBarrierReleasePointerReq, stuff->num_barriers * sizeof(xXIBarrierReleasePointerInfo)); + + info = (xXIBarrierReleasePointerInfo*) &stuff[1]; +-- +cgit v0.10.2 + + diff --git a/patches/source/xorg-server/patch/xorg-server/xorg-server.CVE-2017-12183.diff b/patches/source/xorg-server/patch/xorg-server/xorg-server.CVE-2017-12183.diff new file mode 100644 index 000000000..b88ba950e --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/xorg-server.CVE-2017-12183.diff @@ -0,0 +1,95 @@ +From 55caa8b08c84af2b50fbc936cf334a5a93dd7db5 Mon Sep 17 00:00:00 2001 +From: Nathan Kidd +Date: Fri, 9 Jan 2015 11:43:05 -0500 +Subject: xfixes: unvalidated lengths (CVE-2017-12183) + +v2: Use before swap (Jeremy Huddleston Sequoia) + +v3: Fix wrong XFixesCopyRegion checks (Alan Coopersmith) + +Reviewed-by: Alan Coopersmith +Reviewed-by: Jeremy Huddleston Sequoia +Reviewed-by: Julien Cristau +Signed-off-by: Jeremy Huddleston Sequoia +Signed-off-by: Nathan Kidd +Signed-off-by: Julien Cristau + +diff --git a/xfixes/cursor.c b/xfixes/cursor.c +index c1ab3be..dc447ed 100644 +--- a/xfixes/cursor.c ++++ b/xfixes/cursor.c +@@ -281,6 +281,7 @@ int _X_COLD + SProcXFixesSelectCursorInput(ClientPtr client) + { + REQUEST(xXFixesSelectCursorInputReq); ++ REQUEST_SIZE_MATCH(xXFixesSelectCursorInputReq); + + swaps(&stuff->length); + swapl(&stuff->window); +@@ -414,7 +415,7 @@ ProcXFixesSetCursorName(ClientPtr client) + REQUEST(xXFixesSetCursorNameReq); + Atom atom; + +- REQUEST_AT_LEAST_SIZE(xXFixesSetCursorNameReq); ++ REQUEST_FIXED_SIZE(xXFixesSetCursorNameReq, stuff->nbytes); + VERIFY_CURSOR(pCursor, stuff->cursor, client, DixSetAttrAccess); + tchar = (char *) &stuff[1]; + atom = MakeAtom(tchar, stuff->nbytes, TRUE); +@@ -1007,6 +1008,8 @@ SProcXFixesCreatePointerBarrier(ClientPtr client) + int i; + CARD16 *in_devices = (CARD16 *) &stuff[1]; + ++ REQUEST_AT_LEAST_SIZE(xXFixesCreatePointerBarrierReq); ++ + swaps(&stuff->length); + swaps(&stuff->num_devices); + REQUEST_FIXED_SIZE(xXFixesCreatePointerBarrierReq, pad_to_int32(stuff->num_devices)); +diff --git a/xfixes/region.c b/xfixes/region.c +index e773701..7c0a7d2 100644 +--- a/xfixes/region.c ++++ b/xfixes/region.c +@@ -359,6 +359,7 @@ ProcXFixesCopyRegion(ClientPtr client) + RegionPtr pSource, pDestination; + + REQUEST(xXFixesCopyRegionReq); ++ REQUEST_SIZE_MATCH(xXFixesCopyRegionReq); + + VERIFY_REGION(pSource, stuff->source, client, DixReadAccess); + VERIFY_REGION(pDestination, stuff->destination, client, DixWriteAccess); +@@ -375,7 +376,7 @@ SProcXFixesCopyRegion(ClientPtr client) + REQUEST(xXFixesCopyRegionReq); + + swaps(&stuff->length); +- REQUEST_AT_LEAST_SIZE(xXFixesCopyRegionReq); ++ REQUEST_SIZE_MATCH(xXFixesCopyRegionReq); + swapl(&stuff->source); + swapl(&stuff->destination); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +diff --git a/xfixes/saveset.c b/xfixes/saveset.c +index 2043153..fd9c7a1 100644 +--- a/xfixes/saveset.c ++++ b/xfixes/saveset.c +@@ -62,6 +62,7 @@ int _X_COLD + SProcXFixesChangeSaveSet(ClientPtr client) + { + REQUEST(xXFixesChangeSaveSetReq); ++ REQUEST_SIZE_MATCH(xXFixesChangeSaveSetReq); + + swaps(&stuff->length); + swapl(&stuff->window); +diff --git a/xfixes/xfixes.c b/xfixes/xfixes.c +index 77efd64..248bf02 100644 +--- a/xfixes/xfixes.c ++++ b/xfixes/xfixes.c +@@ -160,6 +160,7 @@ static _X_COLD int + SProcXFixesQueryVersion(ClientPtr client) + { + REQUEST(xXFixesQueryVersionReq); ++ REQUEST_SIZE_MATCH(xXFixesQueryVersionReq); + + swaps(&stuff->length); + swapl(&stuff->majorVersion); +-- +cgit v0.10.2 + + diff --git a/patches/source/xorg-server/patch/xorg-server/xorg-server.CVE-2017-13723.diff b/patches/source/xorg-server/patch/xorg-server/xorg-server.CVE-2017-13723.diff new file mode 100644 index 000000000..6e37be485 --- /dev/null +++ b/patches/source/xorg-server/patch/xorg-server/xorg-server.CVE-2017-13723.diff @@ -0,0 +1,116 @@ +From 94f11ca5cf011ef123bd222cabeaef6f424d76ac Mon Sep 17 00:00:00 2001 +From: Keith Packard +Date: Thu, 27 Jul 2017 10:08:32 -0700 +Subject: xkb: Handle xkb formated string output safely (CVE-2017-13723) + +Generating strings for XKB data used a single shared static buffer, +which offered several opportunities for errors. Use a ring of +resizable buffers instead, to avoid problems when strings end up +longer than anticipated. + +Reviewed-by: Michal Srb +Signed-off-by: Keith Packard +Signed-off-by: Julien Cristau + +diff --git a/xkb/xkbtext.c b/xkb/xkbtext.c +index ead2b1a..d2a2567 100644 +--- a/xkb/xkbtext.c ++++ b/xkb/xkbtext.c +@@ -47,23 +47,27 @@ + + /***====================================================================***/ + +-#define BUFFER_SIZE 512 +- +-static char textBuffer[BUFFER_SIZE]; +-static int tbNext = 0; ++#define NUM_BUFFER 8 ++static struct textBuffer { ++ int size; ++ char *buffer; ++} textBuffer[NUM_BUFFER]; ++static int textBufferIndex; + + static char * + tbGetBuffer(unsigned size) + { +- char *rtrn; ++ struct textBuffer *tb; + +- if (size >= BUFFER_SIZE) +- return NULL; +- if ((BUFFER_SIZE - tbNext) <= size) +- tbNext = 0; +- rtrn = &textBuffer[tbNext]; +- tbNext += size; +- return rtrn; ++ tb = &textBuffer[textBufferIndex]; ++ textBufferIndex = (textBufferIndex + 1) % NUM_BUFFER; ++ ++ if (size > tb->size) { ++ free(tb->buffer); ++ tb->buffer = xnfalloc(size); ++ tb->size = size; ++ } ++ return tb->buffer; + } + + /***====================================================================***/ +@@ -79,8 +83,6 @@ XkbAtomText(Atom atm, unsigned format) + int len; + + len = strlen(atmstr) + 1; +- if (len > BUFFER_SIZE) +- len = BUFFER_SIZE - 2; + rtrn = tbGetBuffer(len); + strlcpy(rtrn, atmstr, len); + } +@@ -128,8 +130,6 @@ XkbVModIndexText(XkbDescPtr xkb, unsigned ndx, unsigned format) + len = strlen(tmp) + 1; + if (format == XkbCFile) + len += 4; +- if (len >= BUFFER_SIZE) +- len = BUFFER_SIZE - 1; + rtrn = tbGetBuffer(len); + if (format == XkbCFile) { + strcpy(rtrn, "vmod_"); +@@ -140,6 +140,8 @@ XkbVModIndexText(XkbDescPtr xkb, unsigned ndx, unsigned format) + return rtrn; + } + ++#define VMOD_BUFFER_SIZE 512 ++ + char * + XkbVModMaskText(XkbDescPtr xkb, + unsigned modMask, unsigned mask, unsigned format) +@@ -147,7 +149,7 @@ XkbVModMaskText(XkbDescPtr xkb, + register int i, bit; + int len; + char *mm, *rtrn; +- char *str, buf[BUFFER_SIZE]; ++ char *str, buf[VMOD_BUFFER_SIZE]; + + if ((modMask == 0) && (mask == 0)) { + rtrn = tbGetBuffer(5); +@@ -173,7 +175,7 @@ XkbVModMaskText(XkbDescPtr xkb, + len = strlen(tmp) + 1 + (str == buf ? 0 : 1); + if (format == XkbCFile) + len += 4; +- if ((str - (buf + len)) <= BUFFER_SIZE) { ++ if ((str - (buf + len)) <= VMOD_BUFFER_SIZE) { + if (str != buf) { + if (format == XkbCFile) + *str++ = '|'; +@@ -199,8 +201,6 @@ XkbVModMaskText(XkbDescPtr xkb, + len = 0; + if (str) + len += strlen(str) + (mm == NULL ? 0 : 1); +- if (len >= BUFFER_SIZE) +- len = BUFFER_SIZE - 1; + rtrn = tbGetBuffer(len + 1); + rtrn[0] = '\0'; + +-- +cgit v0.10.2 + + -- cgit v1.2.3