summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Bragg <robert@linux.intel.com>2011-12-12 00:30:43 +0000
committerAlan Coopersmith <alan.coopersmith@oracle.com>2011-12-13 18:54:30 -0800
commit6086f6c1d0e0a1c9e590879acb2319dea0eb6e96 (patch)
tree022c839a99918494c1b9ecc6ea1727e324f00593
parenta04a45cb94f7f569e6dd77df93258fa167d0a4ea (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.c14
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)) {