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@who-t.net>
This commit is contained in:
Peter Hutterer 2022-07-13 11:33:00 +10:00
parent 18f91b950e
commit 44ae6f4419

View File

@ -5794,7 +5794,8 @@ static unsigned char componentExprLegal[] = {
}; };
static char * static char *
GetComponentSpec(unsigned char **pWire, Bool allowExpr, int *errRtrn) GetComponentSpec(ClientPtr client, xkbGetKbdByNameReq *stuff,
unsigned char **pWire, Bool allowExpr, int *errRtrn)
{ {
int len; int len;
register int i; register int i;
@ -5806,7 +5807,15 @@ GetComponentSpec(unsigned char **pWire, Bool allowExpr, int *errRtrn)
legal = &componentSpecLegal[0]; legal = &componentSpecLegal[0];
wire = *pWire; wire = *pWire;
if (!_XkbCheckRequestBounds(client, stuff, wire, wire + 1)) {
*errRtrn = BadLength;
return NULL;
}
len = (*(unsigned char *) wire++); len = (*(unsigned char *) wire++);
if (!_XkbCheckRequestBounds(client, stuff, wire, wire + len)) {
*errRtrn = BadLength;
return NULL;
}
if (len > 0) { if (len > 0) {
str = calloc(1, len + 1); str = calloc(1, len + 1);
if (str) { if (str) {
@ -5936,17 +5945,17 @@ ProcXkbGetKbdByName(ClientPtr client)
status = Success; status = Success;
str = (unsigned char *) &stuff[1]; 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) { if (keymap) {
free(keymap); free(keymap);
return BadMatch; return BadMatch;
} }
} }
names.keycodes = GetComponentSpec(&str, TRUE, &status); names.keycodes = GetComponentSpec(client, stuff, &str, TRUE, &status);
names.types = GetComponentSpec(&str, TRUE, &status); names.types = GetComponentSpec(client, stuff, &str, TRUE, &status);
names.compat = GetComponentSpec(&str, TRUE, &status); names.compat = GetComponentSpec(client, stuff, &str, TRUE, &status);
names.symbols = GetComponentSpec(&str, TRUE, &status); names.symbols = GetComponentSpec(client, stuff, &str, TRUE, &status);
names.geometry = GetComponentSpec(&str, TRUE, &status); names.geometry = GetComponentSpec(client, stuff, &str, TRUE, &status);
if (status == Success) { if (status == Success) {
len = str - ((unsigned char *) stuff); len = str - ((unsigned char *) stuff);
if ((XkbPaddedSize(len) / 4) != stuff->length) if ((XkbPaddedSize(len) / 4) != stuff->length)