| From 8c29f1607a31dac0911e45a0dd3d74173822b3c9 Mon Sep 17 00:00:00 2001 |
| From: Tobias Stoeckmann <tobias@stoeckmann.org> |
| Date: Sun, 25 Sep 2016 21:22:57 +0200 |
| Subject: The validation of server responses avoids out of boundary accesses. |
| |
| v2: FontNames.c return a NULL list whenever a single |
| length field from the server is incohent. |
| |
| CVE: CVE-2016-7943 |
| Upstream-Status: Backport |
| |
| Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org> |
| Reviewed-by: Matthieu Herrb <matthieu@herrb.eu> |
| Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> |
| |
| diff --git a/src/FontNames.c b/src/FontNames.c |
| index 21dcafe..e55f338 100644 |
| --- a/src/FontNames.c |
| +++ b/src/FontNames.c |
| @@ -66,7 +66,7 @@ int *actualCount) /* RETURN */ |
| |
| if (rep.nFonts) { |
| flist = Xmalloc (rep.nFonts * sizeof(char *)); |
| - if (rep.length < (INT_MAX >> 2)) { |
| + if (rep.length > 0 && rep.length < (INT_MAX >> 2)) { |
| rlen = rep.length << 2; |
| ch = Xmalloc(rlen + 1); |
| /* +1 to leave room for last null-terminator */ |
| @@ -93,11 +93,22 @@ int *actualCount) /* RETURN */ |
| if (ch + length < chend) { |
| flist[i] = ch + 1; /* skip over length */ |
| ch += length + 1; /* find next length ... */ |
| - length = *(unsigned char *)ch; |
| - *ch = '\0'; /* and replace with null-termination */ |
| - count++; |
| - } else |
| - flist[i] = NULL; |
| + if (ch <= chend) { |
| + length = *(unsigned char *)ch; |
| + *ch = '\0'; /* and replace with null-termination */ |
| + count++; |
| + } else { |
| + Xfree(flist); |
| + flist = NULL; |
| + count = 0; |
| + break; |
| + } |
| + } else { |
| + Xfree(flist); |
| + flist = NULL; |
| + count = 0; |
| + break; |
| + } |
| } |
| } |
| *actualCount = count; |
| diff --git a/src/ListExt.c b/src/ListExt.c |
| index be6b989..0516e45 100644 |
| --- a/src/ListExt.c |
| +++ b/src/ListExt.c |
| @@ -55,7 +55,7 @@ char **XListExtensions( |
| |
| if (rep.nExtensions) { |
| list = Xmalloc (rep.nExtensions * sizeof (char *)); |
| - if (rep.length < (INT_MAX >> 2)) { |
| + if (rep.length > 0 && rep.length < (INT_MAX >> 2)) { |
| rlen = rep.length << 2; |
| ch = Xmalloc (rlen + 1); |
| /* +1 to leave room for last null-terminator */ |
| @@ -80,9 +80,13 @@ char **XListExtensions( |
| if (ch + length < chend) { |
| list[i] = ch+1; /* skip over length */ |
| ch += length + 1; /* find next length ... */ |
| - length = *ch; |
| - *ch = '\0'; /* and replace with null-termination */ |
| - count++; |
| + if (ch <= chend) { |
| + length = *ch; |
| + *ch = '\0'; /* and replace with null-termination */ |
| + count++; |
| + } else { |
| + list[i] = NULL; |
| + } |
| } else |
| list[i] = NULL; |
| } |
| diff --git a/src/ModMap.c b/src/ModMap.c |
| index a809aa2..49a5d08 100644 |
| --- a/src/ModMap.c |
| +++ b/src/ModMap.c |
| @@ -42,7 +42,8 @@ XGetModifierMapping(register Display *dpy) |
| GetEmptyReq(GetModifierMapping, req); |
| (void) _XReply (dpy, (xReply *)&rep, 0, xFalse); |
| |
| - if (rep.length < (INT_MAX >> 2)) { |
| + if (rep.length < (INT_MAX >> 2) && |
| + (rep.length >> 1) == rep.numKeyPerModifier) { |
| nbytes = (unsigned long)rep.length << 2; |
| res = Xmalloc(sizeof (XModifierKeymap)); |
| if (res) |
| -- |
| cgit v0.10.2 |
| |