summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Stoeckmann <tobias@stoeckmann.org>2018-07-03 22:31:37 +0200
committerMatthieu Herrb <matthieu@herrb.eu>2018-07-17 15:23:14 +0200
commitd81da209fd4d0c2c9ad0596a8078e58864479d0d (patch)
tree3b1bf53243a2291b8fbf1022e68dbba713a75195
parentb676e62377483df77bcb6472d26b24f901323fa9 (diff)
Validation of server response in XListHosts.
If a server sends an incorrect length in its response, a client is prone to perform an out of boundary read while processing the data. The length field of xHostEntry is used to specify the amount of bytes used to represent the address. It is 16 bit, which means that it is not possible to perform an arbitrary memory access, but it might be enough to read sensitive information, e.g. malloc-related pointers and offsets. Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org> Reviewed-by: Matthieu Herrb <matthieu@herrb.eu>
-rw-r--r--src/LiHosts.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/src/LiHosts.c b/src/LiHosts.c
index 29c36ffb..315e4dbb 100644
--- a/src/LiHosts.c
+++ b/src/LiHosts.c
@@ -119,11 +119,16 @@ XHostAddress *XListHosts (
_XRead (dpy, (char *) buf, nbytes);
for (i = 0; i < reply.nHosts; i++) {
+ if (bp > buf + nbytes - SIZEOF(xHostEntry))
+ goto fail;
op->family = ((xHostEntry *) bp)->family;
op->length =((xHostEntry *) bp)->length;
if (op->family == FamilyServerInterpreted) {
char *tp = (char *) (bp + SIZEOF(xHostEntry));
- char *vp = memchr(tp, 0, op->length);
+ char *vp;
+ if (tp > (char *) (buf + nbytes - op->length))
+ goto fail;
+ vp = memchr(tp, 0, op->length);
if (vp != NULL) {
sip->type = tp;
@@ -138,6 +143,8 @@ XHostAddress *XListHosts (
sip++;
} else {
op->address = (char *) (bp + SIZEOF(xHostEntry));
+ if (op->address > (char *) (buf + nbytes - op->length))
+ goto fail;
}
bp += SIZEOF(xHostEntry) + (((op->length + 3) >> 2) << 2);
op++;
@@ -149,9 +156,9 @@ XHostAddress *XListHosts (
UnlockDisplay(dpy);
SyncHandle();
return (outbuf);
+fail:
+ *enabled = reply.enabled;
+ *nhosts = 0;
+ Xfree(outbuf);
+ return (NULL);
}
-
-
-
-
-