There are 2 potential overflows in xtrans, which may be exploitable.
One of them is documented in <
http://www.securityfocus.com/archive/1/139436>
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);