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:
parent
18f91b950e
commit
44ae6f4419
23
xkb/xkb.c
23
xkb/xkb.c
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue