diff options
author | Tobias Stoeckmann <tobias@stoeckmann.org> | 2018-07-03 22:31:37 +0200 |
---|---|---|
committer | Matthieu Herrb <matthieu@herrb.eu> | 2018-07-17 15:23:14 +0200 |
commit | d81da209fd4d0c2c9ad0596a8078e58864479d0d (patch) | |
tree | 3b1bf53243a2291b8fbf1022e68dbba713a75195 | |
parent | b676e62377483df77bcb6472d26b24f901323fa9 (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.c | 19 |
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); } - - - - - |