Re: X11R6 NetBSD Security Problem

From: Matthieu Herrb (matthieuat_private)
Date: Fri Mar 26 1999 - 12:21:20 PST

  • Next message: Christoforos Karatzinis: "Possible security hole"

    in.telnetd wrote (in a message from Sunday 21)
     >
     > telnetd ~$ ln -s /etc /tmp/.X11-unix
     > telnetd ~$ startx
    
    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 (stat(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;
    +}
    --
    					Matthieu
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 14:40:43 PDT