diff options
author | Robert Bragg <robert@linux.intel.com> | 2011-12-12 00:30:43 +0000 |
---|---|---|
committer | Alan Coopersmith <alan.coopersmith@oracle.com> | 2011-12-13 18:54:30 -0800 |
commit | 6086f6c1d0e0a1c9e590879acb2319dea0eb6e96 (patch) | |
tree | 022c839a99918494c1b9ecc6ea1727e324f00593 | |
parent | a04a45cb94f7f569e6dd77df93258fa167d0a4ea (diff) |
Xtranssock.c: avoid buffer overrun in SocketReopen
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 <robert@linux.intel.com>
Reviewed-by: Alan Coopersmith <alan.coopersmith@oracle.com>
Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
-rw-r--r-- | 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)) { |