There are 2 potential overflows in xtrans, which may be exploitable. One of them is documented in Apply by doing: cd "the directory containing your X11 source dir" patch -p0 < 030_xtrans.patch And then rebuild your X11 tree: cd X11 make build "DESTDIR=/" Note: tcl/tk 8.0.5 is required to build X11 from source. Index: X11/xc/lib/xtrans/Xtrans.c =================================================================== RCS file: /cvs/X11/xc/lib/xtrans/Xtrans.c,v retrieving revision 1.1.1.3 retrieving revision 1.2 diff -u -u -r1.1.1.3 -r1.2 --- X11/xc/lib/xtrans/Xtrans.c 1999/08/24 17:41:25 1.1.1.3 +++ X11/xc/lib/xtrans/Xtrans.c 2000/10/14 15:47:31 1.2 @@ -178,7 +178,7 @@ * a case insensitive match. */ - strncpy (protobuf, protocol, PROTOBUFSIZE); + strncpy (protobuf, protocol, PROTOBUFSIZE - 1); for (i = 0; i < PROTOBUFSIZE && protobuf[i] != '\0'; i++) if (isupper (protobuf[i])) Index: X11/xc/lib/xtrans/Xtranssock.c =================================================================== RCS file: /cvs/X11/xc/lib/xtrans/Xtranssock.c,v retrieving revision 1.4 retrieving revision 1.6 diff -u -u -r1.4 -r1.6 --- X11/xc/lib/xtrans/Xtranssock.c 1999/08/24 18:11:21 1.4 +++ X11/xc/lib/xtrans/Xtranssock.c 2000/10/13 21:04:23 1.6 @@ -754,6 +754,29 @@ } +#ifdef UNIXCONN +static int +set_sun_path(const char *port, const char *upath, char *path) +{ + struct sockaddr_un s; + int maxlen = sizeof(s.sun_path) - 1; + + if (!port || !*port || !path) + return -1; + + if (*port == '/') { /* a full pathname */ + if (strlen(port) > maxlen) + return -1; + sprintf(path, "%s", port); + } else { + if (strlen(port) + strlen(upath) > maxlen) + return -1; + sprintf(path, "%s%s", upath, port); + } + return 0; +} +#endif + #ifdef TRANS_SERVER static int @@ -957,10 +980,9 @@ sockname.sun_family = AF_UNIX; if (port && *port) { - if (*port == '/') { /* a full pathname */ - sprintf (sockname.sun_path, "%s", port); - } else { - sprintf (sockname.sun_path, "%s%s", UNIX_PATH, port); + if (set_sun_path(port, UNIX_PATH, sockname.sun_path) != 0) { + PRMSG (1, "SocketUNIXCreateListener: path too long\n", 0, 0, 0); + return TRANS_CREATE_LISTENER_FAILED; } } else { sprintf (sockname.sun_path, "%s%d", UNIX_PATH, getpid()); @@ -1604,10 +1626,9 @@ sockname.sun_family = AF_UNIX; - if (*port == '/') { /* a full pathname */ - sprintf (sockname.sun_path, "%s", port); - } else { - sprintf (sockname.sun_path, "%s%s", UNIX_PATH, port); + if (set_sun_path(port, UNIX_PATH, sockname.sun_path) != 0) { + PRMSG (1, "SocketUNIXCreateListener: path too long\n", 0, 0, 0); + return TRANS_CREATE_LISTENER_FAILED; } #if defined(BSD44SOCKETS) && !defined(Lynx) @@ -1623,10 +1644,9 @@ * This is gross, but it was in Xlib */ old_sockname.sun_family = AF_UNIX; - if (*port == '/') { /* a full pathname */ - sprintf (old_sockname.sun_path, "%s", port); - } else { - sprintf (old_sockname.sun_path, "%s%s", OLD_UNIX_PATH, port); + if (set_sun_path(port, OLD_UNIX_PATH, old_sockname.sun_path) != 0) { + PRMSG (1, "SocketUNIXConnect: path too long\n", 0, 0, 0); + return TRANS_CONNECT_FAILED; } old_namelen = strlen (old_sockname.sun_path) + sizeof (old_sockname.sun_family);