From 70daf8797594fd9a42685c459a74dad841e3428464fbcb60bf2d27ce59741480 Mon Sep 17 00:00:00 2001 From: Stefan Dirsch Date: Tue, 12 Jul 2022 13:29:47 +0000 Subject: [PATCH] - U_boo1194181-001-xkb-swap-XkbSetDeviceInfo-and-XkbSetDeviceInfoCheck.patch * Out-Of-Bounds Access in CheckSetDeviceIndicators() (CVE-2022-2320, ZDI-CAN-16070, bsc#1194181) - U_boo1194179-001-xkb-rename-xkb_h-to-xkb-procs_h.patch, U_boo1194179-002-xkb-add-request-length-validation-for-XkbSetGeometry.patch * Out-Of-Bounds Access in _CheckSetSections() (CVE-2022-2319, ZDI-CAN-16062, bsc#1194179) OBS-URL: https://build.opensuse.org/package/show/X11:XOrg/xorg-x11-server?expand=0&rev=827 --- ...-001-xkb-rename-xkb_h-to-xkb-procs_h.patch | 155 +++++++++++++++++ ...length-validation-for-XkbSetGeometry.patch | 160 ++++++++++++++++++ ...DeviceInfo-and-XkbSetDeviceInfoCheck.patch | 138 +++++++++++++++ xorg-x11-server.changes | 11 ++ xorg-x11-server.spec | 9 + 5 files changed, 473 insertions(+) create mode 100644 U_boo1194179-001-xkb-rename-xkb_h-to-xkb-procs_h.patch create mode 100644 U_boo1194179-002-xkb-add-request-length-validation-for-XkbSetGeometry.patch create mode 100644 U_boo1194181-001-xkb-swap-XkbSetDeviceInfo-and-XkbSetDeviceInfoCheck.patch diff --git a/U_boo1194179-001-xkb-rename-xkb_h-to-xkb-procs_h.patch b/U_boo1194179-001-xkb-rename-xkb_h-to-xkb-procs_h.patch new file mode 100644 index 0000000..f933406 --- /dev/null +++ b/U_boo1194179-001-xkb-rename-xkb_h-to-xkb-procs_h.patch @@ -0,0 +1,155 @@ +From 04a2689e96b42330718517b2a3950aa2bb1ca017 Mon Sep 17 00:00:00 2001 +From: Peter Hutterer +Date: Mon, 4 Jul 2022 09:42:53 +1000 +Subject: [PATCH] xkb: rename xkb.h to xkb-procs.h + +This header merely defines the various protocol request handlers, so +let's rename it to something less generic and remove its include from +all the files that don't actually need it (which is almost all of them). + +Signed-off-by: Peter Hutterer +Reviewed-by: Olivier Fourdan +--- + test/test_xkb.c | 1 - + xkb/ddxLoad.c | 1 - + xkb/{xkb.h => xkb-procs.h} | 0 + xkb/xkb.c | 2 +- + xkb/xkbActions.c | 1 - + xkb/xkbEvents.c | 1 - + xkb/xkbInit.c | 1 - + xkb/xkbLEDs.c | 1 - + xkb/xkbSwap.c | 2 +- + xkb/xkbUtils.c | 1 - + xkb/xkbfmisc.c | 1 - + 11 files changed, 2 insertions(+), 10 deletions(-) + rename xkb/{xkb.h => xkb-procs.h} (100%) + +diff --git a/test/test_xkb.c b/test/test_xkb.c +index f81a7ed65..a13107390 100644 +--- a/test/test_xkb.c ++++ b/test/test_xkb.c +@@ -48,7 +48,6 @@ + #include "../xkb/xkbgeom.h" + #include + #include "xkbfile.h" +-#include "../xkb/xkb.h" + #include + + #include "tests-common.h" +diff --git a/xkb/ddxLoad.c b/xkb/ddxLoad.c +index f9b7b06d9..2d203ce11 100644 +--- a/xkb/ddxLoad.c ++++ b/xkb/ddxLoad.c +@@ -43,7 +43,6 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. + #define XKBSRV_NEED_FILE_FUNCS + #include + #include +-#include "xkb.h" + + #define PRE_ERROR_MSG "\"The XKEYBOARD keymap compiler (xkbcomp) reports:\"" + #define ERROR_PREFIX "\"> \"" +diff --git a/xkb/xkb.h b/xkb/xkb-procs.h +similarity index 100% +rename from xkb/xkb.h +rename to xkb/xkb-procs.h +diff --git a/xkb/xkb.c b/xkb/xkb.c +index 820cd7166..21c046913 100644 +--- a/xkb/xkb.c ++++ b/xkb/xkb.c +@@ -38,7 +38,7 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. + #include "extnsionst.h" + #include "extinit.h" + #include "xace.h" +-#include "xkb.h" ++#include "xkb-procs.h" + #include "protocol-versions.h" + + #include +diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c +index db29091e7..5e9a6b6d6 100644 +--- a/xkb/xkbActions.c ++++ b/xkb/xkbActions.c +@@ -38,7 +38,6 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. + #include "exevents.h" + #include "eventstr.h" + #include +-#include "xkb.h" + #include + #include "mi.h" + #include "mipointer.h" +diff --git a/xkb/xkbEvents.c b/xkb/xkbEvents.c +index 0bbd66186..f8f65d4a7 100644 +--- a/xkb/xkbEvents.c ++++ b/xkb/xkbEvents.c +@@ -39,7 +39,6 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. + #include "exglobals.h" + #include "windowstr.h" + #include +-#include "xkb.h" + + /***====================================================================***/ + +diff --git a/xkb/xkbInit.c b/xkb/xkbInit.c +index 4108e1b26..de1dd3fe3 100644 +--- a/xkb/xkbInit.c ++++ b/xkb/xkbInit.c +@@ -49,7 +49,6 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. + #include "xkbgeom.h" + #include + #include "xkbfile.h" +-#include "xkb.h" + + #define CREATE_ATOM(s) MakeAtom(s,sizeof(s)-1,1) + +diff --git a/xkb/xkbLEDs.c b/xkb/xkbLEDs.c +index 5792d9fb7..d4690dad9 100644 +--- a/xkb/xkbLEDs.c ++++ b/xkb/xkbLEDs.c +@@ -38,7 +38,6 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. + + #include + #include +-#include "xkb.h" + + /***====================================================================***/ + +diff --git a/xkb/xkbSwap.c b/xkb/xkbSwap.c +index 50cabb90e..efbdb81c1 100644 +--- a/xkb/xkbSwap.c ++++ b/xkb/xkbSwap.c +@@ -36,7 +36,7 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. + #include + #include "xkbstr.h" + #include "extnsionst.h" +-#include "xkb.h" ++#include "xkb-procs.h" + + /* + * REQUEST SWAPPING +diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c +index 8975ade8d..dd089c204 100644 +--- a/xkb/xkbUtils.c ++++ b/xkb/xkbUtils.c +@@ -67,7 +67,6 @@ DEALINGS IN THE SOFTWARE. + #define XKBSRV_NEED_FILE_FUNCS + #include + #include "xkbgeom.h" +-#include "xkb.h" + + /***====================================================================***/ + +diff --git a/xkb/xkbfmisc.c b/xkb/xkbfmisc.c +index 2ecdcd555..fc9197f2d 100644 +--- a/xkb/xkbfmisc.c ++++ b/xkb/xkbfmisc.c +@@ -46,7 +46,6 @@ + #define XKBSRV_NEED_FILE_FUNCS 1 + #include + #include "xkbgeom.h" +-#include "xkb.h" + + unsigned + _XkbKSCheckCase(KeySym ks) +-- +GitLab + diff --git a/U_boo1194179-002-xkb-add-request-length-validation-for-XkbSetGeometry.patch b/U_boo1194179-002-xkb-add-request-length-validation-for-XkbSetGeometry.patch new file mode 100644 index 0000000..db3bd4c --- /dev/null +++ b/U_boo1194179-002-xkb-add-request-length-validation-for-XkbSetGeometry.patch @@ -0,0 +1,160 @@ +@@ -, +, @@ +--- + xkb/xkb.c | 43 ++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 38 insertions(+), 5 deletions(-) +Index: xorg-server-21.1.3/xkb/xkb.c +=================================================================== +--- xorg-server-21.1.3.orig/xkb/xkb.c ++++ xorg-server-21.1.3/xkb/xkb.c +@@ -5157,7 +5157,7 @@ _GetCountedString(char **wire_inout, Cli + } + + static Status +-_CheckSetDoodad(char **wire_inout, ++_CheckSetDoodad(char **wire_inout, xkbSetGeometryReq *req, + XkbGeometryPtr geom, XkbSectionPtr section, ClientPtr client) + { + char *wire; +@@ -5168,6 +5168,9 @@ _CheckSetDoodad(char **wire_inout, + Status status; + + dWire = (xkbDoodadWireDesc *) (*wire_inout); ++ if (!_XkbCheckRequestBounds(client, req, dWire, dWire + 1)) ++ return BadLength; ++ + any = dWire->any; + wire = (char *) &dWire[1]; + if (client->swapped) { +@@ -5270,7 +5273,7 @@ _CheckSetDoodad(char **wire_inout, + } + + static Status +-_CheckSetOverlay(char **wire_inout, ++_CheckSetOverlay(char **wire_inout, xkbSetGeometryReq *req, + XkbGeometryPtr geom, XkbSectionPtr section, ClientPtr client) + { + register int r; +@@ -5281,6 +5284,9 @@ _CheckSetOverlay(char **wire_inout, + + wire = *wire_inout; + olWire = (xkbOverlayWireDesc *) wire; ++ if (!_XkbCheckRequestBounds(client, req, olWire, olWire + 1)) ++ return BadLength; ++ + if (client->swapped) { + swapl(&olWire->name); + } +@@ -5292,6 +5298,9 @@ _CheckSetOverlay(char **wire_inout, + xkbOverlayKeyWireDesc *kWire; + XkbOverlayRowPtr row; + ++ if (!_XkbCheckRequestBounds(client, req, rWire, rWire + 1)) ++ return BadLength; ++ + if (rWire->rowUnder > section->num_rows) { + client->errorValue = _XkbErrCode4(0x20, r, section->num_rows, + rWire->rowUnder); +@@ -5300,6 +5309,9 @@ _CheckSetOverlay(char **wire_inout, + row = XkbAddGeomOverlayRow(ol, rWire->rowUnder, rWire->nKeys); + kWire = (xkbOverlayKeyWireDesc *) &rWire[1]; + for (k = 0; k < rWire->nKeys; k++, kWire++) { ++ if (!_XkbCheckRequestBounds(client, req, kWire, kWire + 1)) ++ return BadLength; ++ + if (XkbAddGeomOverlayKey(ol, row, + (char *) kWire->over, + (char *) kWire->under) == NULL) { +@@ -5333,6 +5345,9 @@ _CheckSetSections(XkbGeometryPtr geom, + register int r; + xkbRowWireDesc *rWire; + ++ if (!_XkbCheckRequestBounds(client, req, sWire, sWire + 1)) ++ return BadLength; ++ + if (client->swapped) { + swapl(&sWire->name); + swaps(&sWire->top); +@@ -5358,6 +5373,9 @@ _CheckSetSections(XkbGeometryPtr geom, + XkbRowPtr row; + xkbKeyWireDesc *kWire; + ++ if (!_XkbCheckRequestBounds(client, req, rWire, rWire + 1)) ++ return BadLength; ++ + if (client->swapped) { + swaps(&rWire->top); + swaps(&rWire->left); +@@ -5372,6 +5390,9 @@ _CheckSetSections(XkbGeometryPtr geom, + for (k = 0; k < rWire->nKeys; k++) { + XkbKeyPtr key; + ++ if (!_XkbCheckRequestBounds(client, req, kWire, kWire + 1)) ++ return BadLength; ++ + key = XkbAddGeomKey(row); + if (!key) + return BadAlloc; +@@ -5397,7 +5418,7 @@ _CheckSetSections(XkbGeometryPtr geom, + register int d; + + for (d = 0; d < sWire->nDoodads; d++) { +- status = _CheckSetDoodad(&wire, geom, section, client); ++ status = _CheckSetDoodad(&wire, req, geom, section, client); + if (status != Success) + return status; + } +@@ -5406,7 +5427,7 @@ _CheckSetSections(XkbGeometryPtr geom, + register int o; + + for (o = 0; o < sWire->nOverlays; o++) { +- status = _CheckSetOverlay(&wire, geom, section, client); ++ status = _CheckSetOverlay(&wire, req, geom, section, client); + if (status != Success) + return status; + } +@@ -5440,6 +5461,9 @@ _CheckSetShapes(XkbGeometryPtr geom, + xkbOutlineWireDesc *olWire; + XkbOutlinePtr ol; + ++ if (!_XkbCheckRequestBounds(client, req, shapeWire, shapeWire + 1)) ++ return BadLength; ++ + shape = + XkbAddGeomShape(geom, shapeWire->name, shapeWire->nOutlines); + if (!shape) +@@ -5450,12 +5474,18 @@ _CheckSetShapes(XkbGeometryPtr geom, + XkbPointPtr pt; + xkbPointWireDesc *ptWire; + ++ if (!_XkbCheckRequestBounds(client, req, olWire, olWire + 1)) ++ return BadLength; ++ + ol = XkbAddGeomOutline(shape, olWire->nPoints); + if (!ol) + return BadAlloc; + ol->corner_radius = olWire->cornerRadius; + ptWire = (xkbPointWireDesc *) &olWire[1]; + for (p = 0, pt = ol->points; p < olWire->nPoints; p++, pt++) { ++ if (!_XkbCheckRequestBounds(client, req, ptWire, ptWire + 1)) ++ return BadLength; ++ + pt->x = ptWire[p].x; + pt->y = ptWire[p].y; + if (client->swapped) { +@@ -5561,12 +5591,15 @@ _CheckSetGeom(XkbGeometryPtr geom, xkbSe + return status; + + for (i = 0; i < req->nDoodads; i++) { +- status = _CheckSetDoodad(&wire, geom, NULL, client); ++ status = _CheckSetDoodad(&wire, req, geom, NULL, client); + if (status != Success) + return status; + } + + for (i = 0; i < req->nKeyAliases; i++) { ++ if (!_XkbCheckRequestBounds(client, req, wire, wire + XkbKeyNameLength)) ++ return BadLength; ++ + if (XkbAddGeomKeyAlias(geom, &wire[XkbKeyNameLength], wire) == NULL) + return BadAlloc; + wire += 2 * XkbKeyNameLength; diff --git a/U_boo1194181-001-xkb-swap-XkbSetDeviceInfo-and-XkbSetDeviceInfoCheck.patch b/U_boo1194181-001-xkb-swap-XkbSetDeviceInfo-and-XkbSetDeviceInfoCheck.patch new file mode 100644 index 0000000..e1ab922 --- /dev/null +++ b/U_boo1194181-001-xkb-swap-XkbSetDeviceInfo-and-XkbSetDeviceInfoCheck.patch @@ -0,0 +1,138 @@ +Index: xorg-server-21.1.3/xkb/xkb.c +=================================================================== +--- xorg-server-21.1.3.orig/xkb/xkb.c ++++ xorg-server-21.1.3/xkb/xkb.c +@@ -6551,7 +6551,8 @@ ProcXkbGetDeviceInfo(ClientPtr client) + static char * + CheckSetDeviceIndicators(char *wire, + DeviceIntPtr dev, +- int num, int *status_rtrn, ClientPtr client) ++ int num, int *status_rtrn, ClientPtr client, ++ xkbSetDeviceInfoReq * stuff) + { + xkbDeviceLedsWireDesc *ledWire; + int i; +@@ -6559,6 +6560,11 @@ CheckSetDeviceIndicators(char *wire, + + ledWire = (xkbDeviceLedsWireDesc *) wire; + for (i = 0; i < num; i++) { ++ if (!_XkbCheckRequestBounds(client, stuff, ledWire, ledWire + 1)) { ++ *status_rtrn = BadLength; ++ return (char *) ledWire; ++ } ++ + if (client->swapped) { + swaps(&ledWire->ledClass); + swaps(&ledWire->ledID); +@@ -6586,6 +6592,11 @@ CheckSetDeviceIndicators(char *wire, + atomWire = (CARD32 *) &ledWire[1]; + if (nNames > 0) { + for (n = 0; n < nNames; n++) { ++ if (!_XkbCheckRequestBounds(client, stuff, atomWire, atomWire + 1)) { ++ *status_rtrn = BadLength; ++ return (char *) atomWire; ++ } ++ + if (client->swapped) { + swapl(atomWire); + } +@@ -6597,6 +6608,10 @@ CheckSetDeviceIndicators(char *wire, + mapWire = (xkbIndicatorMapWireDesc *) atomWire; + if (nMaps > 0) { + for (n = 0; n < nMaps; n++) { ++ if (!_XkbCheckRequestBounds(client, stuff, mapWire, mapWire + 1)) { ++ *status_rtrn = BadLength; ++ return (char *) mapWire; ++ } + if (client->swapped) { + swaps(&mapWire->virtualMods); + swapl(&mapWire->ctrls); +@@ -6648,11 +6663,6 @@ SetDeviceIndicators(char *wire, + xkbIndicatorMapWireDesc *mapWire; + XkbSrvLedInfoPtr sli; + +- if (!_XkbCheckRequestBounds(client, stuff, ledWire, ledWire + 1)) { +- *status_rtrn = BadLength; +- return (char *) ledWire; +- } +- + namec = mapc = statec = 0; + sli = XkbFindSrvLedInfo(dev, ledWire->ledClass, ledWire->ledID, + XkbXI_IndicatorMapsMask); +@@ -6671,10 +6681,6 @@ SetDeviceIndicators(char *wire, + memset((char *) sli->names, 0, XkbNumIndicators * sizeof(Atom)); + for (n = 0, bit = 1; n < XkbNumIndicators; n++, bit <<= 1) { + if (ledWire->namesPresent & bit) { +- if (!_XkbCheckRequestBounds(client, stuff, atomWire, atomWire + 1)) { +- *status_rtrn = BadLength; +- return (char *) atomWire; +- } + sli->names[n] = (Atom) *atomWire; + if (sli->names[n] == None) + ledWire->namesPresent &= ~bit; +@@ -6692,10 +6698,6 @@ SetDeviceIndicators(char *wire, + if (ledWire->mapsPresent) { + for (n = 0, bit = 1; n < XkbNumIndicators; n++, bit <<= 1) { + if (ledWire->mapsPresent & bit) { +- if (!_XkbCheckRequestBounds(client, stuff, mapWire, mapWire + 1)) { +- *status_rtrn = BadLength; +- return (char *) mapWire; +- } + sli->maps[n].flags = mapWire->flags; + sli->maps[n].which_groups = mapWire->whichGroups; + sli->maps[n].groups = mapWire->groups; +@@ -6731,13 +6733,17 @@ SetDeviceIndicators(char *wire, + } + + static int +-_XkbSetDeviceInfo(ClientPtr client, DeviceIntPtr dev, ++_XkbSetDeviceInfoCheck(ClientPtr client, DeviceIntPtr dev, + xkbSetDeviceInfoReq * stuff) + { + char *wire; + + wire = (char *) &stuff[1]; + if (stuff->change & XkbXI_ButtonActionsMask) { ++ int sz = stuff->nBtns * SIZEOF(xkbActionWireDesc); ++ if (!_XkbCheckRequestBounds(client, stuff, wire, (char *) wire + sz)) ++ return BadLength; ++ + if (!dev->button) { + client->errorValue = _XkbErrCode2(XkbErr_BadClass, ButtonClass); + return XkbKeyboardErrorCode; +@@ -6748,13 +6754,13 @@ _XkbSetDeviceInfo(ClientPtr client, Devi + dev->button->numButtons); + return BadMatch; + } +- wire += (stuff->nBtns * SIZEOF(xkbActionWireDesc)); ++ wire += sz; + } + if (stuff->change & XkbXI_IndicatorsMask) { + int status = Success; + + wire = CheckSetDeviceIndicators(wire, dev, stuff->nDeviceLedFBs, +- &status, client); ++ &status, client, stuff); + if (status != Success) + return status; + } +@@ -6765,8 +6771,8 @@ _XkbSetDeviceInfo(ClientPtr client, Devi + } + + static int +-_XkbSetDeviceInfoCheck(ClientPtr client, DeviceIntPtr dev, +- xkbSetDeviceInfoReq * stuff) ++_XkbSetDeviceInfo(ClientPtr client, DeviceIntPtr dev, ++ xkbSetDeviceInfoReq * stuff) + { + char *wire; + xkbExtensionDeviceNotify ed; +@@ -6790,8 +6796,6 @@ _XkbSetDeviceInfoCheck(ClientPtr client, + if (stuff->firstBtn + stuff->nBtns > nBtns) + return BadValue; + sz = stuff->nBtns * SIZEOF(xkbActionWireDesc); +- if (!_XkbCheckRequestBounds(client, stuff, wire, (char *) wire + sz)) +- return BadLength; + memcpy((char *) &acts[stuff->firstBtn], (char *) wire, sz); + wire += sz; + ed.reason |= XkbXI_ButtonActionsMask; diff --git a/xorg-x11-server.changes b/xorg-x11-server.changes index 3efca36..09e65fb 100644 --- a/xorg-x11-server.changes +++ b/xorg-x11-server.changes @@ -1,3 +1,14 @@ +------------------------------------------------------------------- +Wed Jul 6 12:21:11 UTC 2022 - Stefan Dirsch + +- U_boo1194181-001-xkb-swap-XkbSetDeviceInfo-and-XkbSetDeviceInfoCheck.patch + * Out-Of-Bounds Access in CheckSetDeviceIndicators() + (CVE-2022-2320, ZDI-CAN-16070, bsc#1194181) +- U_boo1194179-001-xkb-rename-xkb_h-to-xkb-procs_h.patch, + U_boo1194179-002-xkb-add-request-length-validation-for-XkbSetGeometry.patch + * Out-Of-Bounds Access in _CheckSetSections() + (CVE-2022-2319, ZDI-CAN-16062, bsc#1194179) + ------------------------------------------------------------------- Tue May 10 13:04:38 UTC 2022 - Dirk Müller diff --git a/xorg-x11-server.spec b/xorg-x11-server.spec index 7709ecf..464607f 100644 --- a/xorg-x11-server.spec +++ b/xorg-x11-server.spec @@ -249,6 +249,12 @@ Patch1950: U_Fix-build-with-gcc-12.patch Patch1960: u_sync-pci-ids-with-Mesa-22.0.0.patch +#CVE-2022-2320, ZDI-CAN-16070, bsc#1194181 +Patch2001: U_boo1194181-001-xkb-swap-XkbSetDeviceInfo-and-XkbSetDeviceInfoCheck.patch +#CVE-2022-2319, ZDI-CAN-16062, bsc#1194179 +Patch2101: U_boo1194179-001-xkb-rename-xkb_h-to-xkb-procs_h.patch +Patch2102: U_boo1194179-002-xkb-add-request-length-validation-for-XkbSetGeometry.patch + %description This package contains the X.Org Server. @@ -407,6 +413,9 @@ sh %{SOURCE92} --verify . %{SOURCE91} %patch1940 -p1 %patch1950 -p1 %patch1960 -p1 +%patch2001 -p1 +%patch2101 -p1 +%patch2102 -p1 %build # We have some -z now related errors during X default startup (boo#1197994):