[PATCH] Fix overflow of ConnectionOutput->size and ->count

Peter Harris pharris at opentext.com
Mon Nov 17 11:31:24 PST 2014


When (long) is larger than (int), and when realloc succeeds with sizes
larger than INT_MAX, ConnectionOutput->size and ConnectionOutput->count
overflow and become negative.

When ConnectionOutput->count is negative, InsertIOV does not actually
insert an IOV, and FlushClient goes into an infinite loop of writev(fd,
iov, 0) [an empty list].

Avoid this situation by killing the client when it has more than INT_MAX
unread bytes of data.

Signed-off-by: Peter Harris <pharris at opentext.com>
---

Alternatively, we could change ->size and ->count to long (or ssize_t or
ptrdiff_t).

 os/io.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/os/io.c b/os/io.c
index 8181a86..1084c9a 100644
--- a/os/io.c
+++ b/os/io.c
@@ -971,10 +971,11 @@ FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount)
             }
 
             if (notWritten > oco->size) {
-                unsigned char *obuf;
+                unsigned char *obuf = NULL;
 
-                obuf = (unsigned char *) realloc(oco->buf,
-                                                 notWritten + BUFSIZE);
+                if (notWritten + BUFSIZE <= INT_MAX) {
+                    obuf = realloc(oco->buf, notWritten + BUFSIZE);
+                }
                 if (!obuf) {
                     _XSERVTransDisconnect(oc->trans_conn);
                     _XSERVTransClose(oc->trans_conn);
-- 
2.1.0



More information about the xorg-devel mailing list