xserver: Branch 'master' - 4 commits
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Fri Jul 22 11:42:21 UTC 2022
xkb/xkb.c | 54 ++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 42 insertions(+), 12 deletions(-)
New commits:
commit 11beef0b7f1ed290348e45618e5fa0d2bffcb72e
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date: Tue Jul 5 12:06:20 2022 +1000
xkb: proof GetCountedString against request length attacks
GetCountedString did a check for the whole string to be within the
request buffer but not for the initial 2 bytes that contain the length
field. A swapped client could send a malformed request to trigger a
swaps() on those bytes, writing into random memory.
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
diff --git a/xkb/xkb.c b/xkb/xkb.c
index f42f59ef3..1841cff26 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -5137,6 +5137,11 @@ _GetCountedString(char **wire_inout, ClientPtr client, char **str)
CARD16 len;
wire = *wire_inout;
+
+ if (client->req_len <
+ bytes_to_int32(wire + 2 - (char *) client->requestBuffer))
+ return BadValue;
+
len = *(CARD16 *) wire;
if (client->swapped) {
swaps(&len);
commit 1bb7767f19969ee6b109f7424ff97738752d18c9
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date: Wed Jul 13 11:38:16 2022 +1000
xkb: length-check XkbListComponents before accessing the fields
Each string length field was accessed before checking whether that byte
was actually part of the client request. No real harm here since it
would immediately fail with BadLength anyway, but let's be correct here.
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
diff --git a/xkb/xkb.c b/xkb/xkb.c
index 0c920393d..f42f59ef3 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -5870,6 +5870,8 @@ ProcXkbListComponents(ClientPtr client)
* length wrong. */
str = (unsigned char *) &stuff[1];
for (i = 0; i < 6; i++) {
+ if (!_XkbCheckRequestBounds(client, stuff, str, str + 1))
+ return BadLength;
size = *((uint8_t *)str);
len = (str + size + 1) - ((unsigned char *) stuff);
if ((XkbPaddedSize(len) / 4) > stuff->length)
commit 44ae6f44192f5edeaf5ac082870bbdf3262071ef
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date: Wed Jul 13 11:33:00 2022 +1000
xkb: length-check XkbGetKbdByName before accessing the fields
This request accessed &stuff[1] before length-checking everything. The
check was performed afterwards so invalid requests would return
BadLength anyway, but let's do this before we actually access the
memory.
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
diff --git a/xkb/xkb.c b/xkb/xkb.c
index b79a269e3..0c920393d 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -5794,7 +5794,8 @@ static unsigned char componentExprLegal[] = {
};
static char *
-GetComponentSpec(unsigned char **pWire, Bool allowExpr, int *errRtrn)
+GetComponentSpec(ClientPtr client, xkbGetKbdByNameReq *stuff,
+ unsigned char **pWire, Bool allowExpr, int *errRtrn)
{
int len;
register int i;
@@ -5806,7 +5807,15 @@ GetComponentSpec(unsigned char **pWire, Bool allowExpr, int *errRtrn)
legal = &componentSpecLegal[0];
wire = *pWire;
+ if (!_XkbCheckRequestBounds(client, stuff, wire, wire + 1)) {
+ *errRtrn = BadLength;
+ return NULL;
+ }
len = (*(unsigned char *) wire++);
+ if (!_XkbCheckRequestBounds(client, stuff, wire, wire + len)) {
+ *errRtrn = BadLength;
+ return NULL;
+ }
if (len > 0) {
str = calloc(1, len + 1);
if (str) {
@@ -5936,17 +5945,17 @@ ProcXkbGetKbdByName(ClientPtr client)
status = Success;
str = (unsigned char *) &stuff[1];
{
- char *keymap = GetComponentSpec(&str, TRUE, &status); /* keymap, unsupported */
+ char *keymap = GetComponentSpec(client, stuff, &str, TRUE, &status); /* keymap, unsupported */
if (keymap) {
free(keymap);
return BadMatch;
}
}
- names.keycodes = GetComponentSpec(&str, TRUE, &status);
- names.types = GetComponentSpec(&str, TRUE, &status);
- names.compat = GetComponentSpec(&str, TRUE, &status);
- names.symbols = GetComponentSpec(&str, TRUE, &status);
- names.geometry = GetComponentSpec(&str, TRUE, &status);
+ names.keycodes = GetComponentSpec(client, stuff, &str, TRUE, &status);
+ names.types = GetComponentSpec(client, stuff, &str, TRUE, &status);
+ names.compat = GetComponentSpec(client, stuff, &str, TRUE, &status);
+ names.symbols = GetComponentSpec(client, stuff, &str, TRUE, &status);
+ names.geometry = GetComponentSpec(client, stuff, &str, TRUE, &status);
if (status == Success) {
len = str - ((unsigned char *) stuff);
if ((XkbPaddedSize(len) / 4) != stuff->length)
commit 18f91b950e22c2a342a4fbc55e9ddf7534a707d2
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date: Wed Jul 13 11:23:09 2022 +1000
xkb: fix some possible memleaks in XkbGetKbdByName
GetComponentByName returns an allocated string, so let's free that if we
fail somewhere.
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
diff --git a/xkb/xkb.c b/xkb/xkb.c
index 4692895db..b79a269e3 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -5935,18 +5935,32 @@ ProcXkbGetKbdByName(ClientPtr client)
xkb = dev->key->xkbInfo->desc;
status = Success;
str = (unsigned char *) &stuff[1];
- if (GetComponentSpec(&str, TRUE, &status)) /* keymap, unsupported */
- return BadMatch;
+ {
+ char *keymap = GetComponentSpec(&str, TRUE, &status); /* keymap, unsupported */
+ if (keymap) {
+ free(keymap);
+ return BadMatch;
+ }
+ }
names.keycodes = GetComponentSpec(&str, TRUE, &status);
names.types = GetComponentSpec(&str, TRUE, &status);
names.compat = GetComponentSpec(&str, TRUE, &status);
names.symbols = GetComponentSpec(&str, TRUE, &status);
names.geometry = GetComponentSpec(&str, TRUE, &status);
- if (status != Success)
+ if (status == Success) {
+ len = str - ((unsigned char *) stuff);
+ if ((XkbPaddedSize(len) / 4) != stuff->length)
+ status = BadLength;
+ }
+
+ if (status != Success) {
+ free(names.keycodes);
+ free(names.types);
+ free(names.compat);
+ free(names.symbols);
+ free(names.geometry);
return status;
- len = str - ((unsigned char *) stuff);
- if ((XkbPaddedSize(len) / 4) != stuff->length)
- return BadLength;
+ }
CHK_MASK_LEGAL(0x01, stuff->want, XkbGBN_AllComponentsMask);
CHK_MASK_LEGAL(0x02, stuff->need, XkbGBN_AllComponentsMask);
More information about the xorg-commit
mailing list