This function was constructing an address from a port string allocating
a buffer according to the size of the string but then later copying
the address according to sizeof(struct sockaddr).

This patch ensures that we allocate a struct sockaddr buffer with enough
space for the port string to be copied into sa_data[] and uses that
combined length to determine how much should be copied at the end of the
function.

This fixes a crash when using xwayland which uses ListenOnOpenFD() that
will call _XSERVTransReopenCOTSServer() with a short port string like
":1".

Signed-off-by: Robert Bragg <[email protected]>
---
 Xtranssock.c |   14 ++++++++------
 1 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/Xtranssock.c b/Xtranssock.c
index 66f9862..dfa41cf 100644
--- a/Xtranssock.c
+++ b/Xtranssock.c
@@ -458,6 +458,7 @@ TRANS(SocketReopen) (int i _X_UNUSED, int type, int fd, 
char *port)
     XtransConnInfo     ciptr;
     int portlen;
     struct sockaddr *addr;
+    size_t addrlen;
 
     prmsg (3,"SocketReopen(%d,%d,%s)\n", type, fd, port);
 
@@ -488,26 +489,27 @@ TRANS(SocketReopen) (int i _X_UNUSED, int type, int fd, 
char *port)
 
     ciptr->fd = fd;
 
-    if ((addr = calloc (1, portlen + 2)) == NULL) {
+    addrlen = portlen + offsetof(struct sockaddr, sa_data);
+    if ((addr = calloc (1, addrlen)) == NULL) {
        prmsg (1, "SocketReopen: malloc(addr) failed\n");
        free (ciptr);
        return NULL;
     }
     ciptr->addr = (char *) addr;
-    ciptr->addrlen = portlen + 2;
+    ciptr->addrlen = addrlen;
 
-    if ((ciptr->peeraddr = calloc (1, portlen + 2)) == NULL) {
+    if ((ciptr->peeraddr = calloc (1, addrlen)) == NULL) {
        prmsg (1, "SocketReopen: malloc(portaddr) failed\n");
        free (addr);
        free (ciptr);
        return NULL;
     }
-    ciptr->peeraddrlen = portlen + 2;
+    ciptr->peeraddrlen = addrlen;
 
     /* Initialize ciptr structure as if it were a normally-opened unix socket 
*/
     ciptr->flags = TRANS_LOCAL | TRANS_NOUNLINK;
 #ifdef BSD44SOCKETS
-    addr->sa_len = portlen + 1;
+    addr->sa_len = addrlen;
 #endif
     addr->sa_family = AF_UNIX;
 #ifdef HAS_STRLCPY
@@ -516,7 +518,7 @@ TRANS(SocketReopen) (int i _X_UNUSED, int type, int fd, 
char *port)
     strncpy(addr->sa_data, port, portlen);
 #endif
     ciptr->family = AF_UNIX;
-    memcpy(ciptr->peeraddr, ciptr->addr, sizeof(struct sockaddr));
+    memcpy(ciptr->peeraddr, ciptr->addr, addrlen);
     ciptr->port = rindex(addr->sa_data, ':');
     if (ciptr->port == NULL) {
        if (is_numeric(addr->sa_data)) {
-- 
1.7.7.3

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to