[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

X Strike Force XFree86 SVN commit: r2270 - in trunk/debian: . patches



Author: branden
Date: 2005-05-26 12:25:58 -0500 (Thu, 26 May 2005)
New Revision: 2270

Modified:
   trunk/debian/CHANGESETS
   trunk/debian/TODO
   trunk/debian/changelog
   trunk/debian/patches/087_SECURITY_libXpm_vulnerabilities.diff
Log:
Replace s_popen()-based fix for CAN-2004-0914 with a better fix from
freedesktop.org xorg CVS.  There were several problems with s_popen(),
some merely functional, and some themselves security-flawed.  There does
not appear to be a MITRE CVE candidate ID for this problem.  The only
differences between the Xpm library code in this package release and that
in freedesktop.org xorg CVS HEAD as of 2005-05-26 are 1) whitespace
differences; 2) RCS keyword differences; 3) preprocessor directives to
support autotoolization of the library; and 4) support for pre-ANSI C
compilers in function prototypes.  (Closes: #308783)


Modified: trunk/debian/CHANGESETS
===================================================================
--- trunk/debian/CHANGESETS	2005-05-25 06:54:33 UTC (rev 2269)
+++ trunk/debian/CHANGESETS	2005-05-26 17:25:58 UTC (rev 2270)
@@ -29,4 +29,15 @@
 also adds a header self-inclusion guard to dpms.h.
     2269
 
+Replace s_popen()-based fix for CAN-2004-0914 with a better fix from
+freedesktop.org xorg CVS.  There were several problems with s_popen(),
+some merely functional, and some themselves security-flawed.  There does
+not appear to be a MITRE CVE candidate ID for this problem.  The only
+differences between the Xpm library code in this package release and that
+in freedesktop.org xorg CVS HEAD as of 2005-05-26 are 1) whitespace
+differences; 2) RCS keyword differences; 3) preprocessor directives to
+support autotoolization of the library; and 4) support for pre-ANSI C
+compilers in function prototypes.  (Closes: #308783)
+    2270
+
 vim:set ai et sts=4 sw=4 tw=80:

Modified: trunk/debian/TODO
===================================================================
--- trunk/debian/TODO	2005-05-25 06:54:33 UTC (rev 2269)
+++ trunk/debian/TODO	2005-05-26 17:25:58 UTC (rev 2270)
@@ -16,26 +16,7 @@
 
 4.3.0.dfsg.1-14
 ---------------
-* Grab Xpm library fixes from freedesktop.org xorg CVS:
-  + Replace security-flawed s_popen() fix for CAN-2004-0914 with better fix by
-    Alex Reisen and Matthieu Herrb.
-    * extras/Xpm/lib/RdFToI.c:
-    * extras/Xpm/lib/WrFFrI.c:
-    * lib/Xpm/Imakefile:
-      Replace s_popen() by a more specific function that allows only
-      one command in the pipe. Remove extraneous tests on file names
-      that broke some applications. From Alex Reisen in Bugzilla #1920.
-    * more s_open() cleanup.
-    * Fix incomplete merge.
-    * Remove s_open.c references in (unused) Imakefile too.
 
-    Changes needed:
-        xc/extras/Xpm/lib/RdFToI.c              1.3 -> 1.6
-        xc/extras/Xpm/lib/WrFFrI.c              1.4 -> 1.5
-        xc/extras/Xpm/lib/s_popen.c             DELETE
-        xc/extras/Xpm/Imakefile                 1.2 -> 1.3
-        xc/lib/Xpm/Imakefile                    1.4 -> 1.5
-
 Post 4.3.0-1
 ------------
 * Rewrite xserver-xfree86 debconfage, possibly as xserver-xorg debconfage.  Joey

Modified: trunk/debian/changelog
===================================================================
--- trunk/debian/changelog	2005-05-25 06:54:33 UTC (rev 2269)
+++ trunk/debian/changelog	2005-05-26 17:25:58 UTC (rev 2270)
@@ -2,10 +2,17 @@
 
   Urgency set to high due to fix for security flaw (see below).
 
-  Changes by David Nusinow:
+  Changes by David Nusinow and Branden Robinson:
 
-  * Backport libxpm from X.org stable release (099za_libxpm_spopen_fix.diff).
-    (Closes: #308783)
+  * Replace s_popen()-based fix for CAN-2004-0914 with a better fix from
+    freedesktop.org xorg CVS.  There were several problems with s_popen(),
+    some merely functional, and some themselves security-flawed.  There does
+    not appear to be a MITRE CVE candidate ID for this problem.  The only
+    differences between the Xpm library code in this package release and that
+    in freedesktop.org xorg CVS HEAD as of 2005-05-26 are 1) whitespace
+    differences; 2) RCS keyword differences; 3) preprocessor directives to
+    support autotoolization of the library; and 4) support for pre-ANSI C
+    compilers in function declarations.  (Closes: #308783)
 
   Changes by Branden Robinson:
 
@@ -20,7 +27,7 @@
     <URL: https://bugs.freedesktop.org/show_bug.cgi?id=830 >.  The DPMS fix
     also adds a header self-inclusion guard to dpms.h.
 
- -- Branden Robinson <branden@debian.org>  Wed, 25 May 2005 01:45:55 -0500
+ -- Branden Robinson <branden@debian.org>  Wed, 25 May 2005 02:57:44 -0500
 
 xfree86 (4.3.0.dfsg.1-13) unstable; urgency=high
 

Modified: trunk/debian/patches/087_SECURITY_libXpm_vulnerabilities.diff
===================================================================
--- trunk/debian/patches/087_SECURITY_libXpm_vulnerabilities.diff	2005-05-25 06:54:33 UTC (rev 2269)
+++ trunk/debian/patches/087_SECURITY_libXpm_vulnerabilities.diff	2005-05-26 17:25:58 UTC (rev 2270)
@@ -137,11 +137,48 @@
 
   ( https://bugs.freedesktop.org/show_bug.cgi?id=1920 )
 
-This patch by Matthieu Herrb and others.
+Patch updated on 2005-05-25 to replace s_popen()-based fix for
+CAN-2004-0914 with a better fix from X.Org CVS HEAD.  There were several
+problems with s_popen(), some merely functional, and some themselves
+security-flawed.  There does not appear to be a MITRE CVE candidate ID for
+this problem.  Quoting Matej Vela:
 
-diff -urN xc~/extras/Xpm/lib/Attrib.c xc/extras/Xpm/lib/Attrib.c
---- xc~/extras/Xpm/lib/Attrib.c	2005-03-13 01:32:36.000000000 -0500
-+++ xc/extras/Xpm/lib/Attrib.c	2005-03-13 01:34:39.000000000 -0500
+  The CAN-2004-0914 patch introduced a s_popen() function as a safe
+  replacement for popen().  Instead of invoking a shell, it splits
+  arguments on whitespace and passes the command directly to execvp(3).
+  However, it doesn't handle quoting or redirection, so code like
+
+  WrFFrI.c:339:       snprintf(buf, sizeof(buf), "gzip -q > \"%s\"", filename);
+  WrFFrI.c:340:       if (!(mdata->stream.file = s_popen(buf, "w")))
+
+  results in a ">" argument and superfluous quotes:
+
+  execve("/bin/gzip", ["gzip", ">", "\"foo.gz\""], [/* 19 vars */])
+
+  This completely breaks the transparent compression and decompression.
+
+  Furthermore, since gzip processes all arguments regardless of errors, an
+  attacker can use filenames with whitespace to compress arbitrary files:
+  (xpmtest taken from <https://bugs.freedesktop.org/show_bug.cgi?id=1920>)
+
+  # ./xpmtest crab.xpm 'fnord -v /etc/hosts.deny fnord.gz'
+  w=28, h=28, cpp=2, cols=6, vmask=00000000, hotspot=0,0
+  gzip: >: No such file or directory
+  gzip: "fnord: No such file or directory
+  /etc/hosts.deny:       -50.0% -- replaced with /etc/hosts.deny.gz
+  gzip: fnord.gz": No such file or directory
+
+  The above would effectively disable TCP wrappers.  The -r option can be
+  used to compress whole directory trees.
+
+  s_popen() also has issues with error handling, signals, and runaway child
+  processes.
+
+This patch by Matthieu Herrb, Alex Reisen, and others.
+
+diff -urN xc/extras/Xpm/lib~/Attrib.c xc/extras/Xpm/lib/Attrib.c
+--- xc/extras/Xpm/lib~/Attrib.c	2005-05-25 02:24:33.256307715 -0500
++++ xc/extras/Xpm/lib/Attrib.c	2005-05-25 01:58:18.000000000 -0500
 @@ -32,13 +32,15 @@
  *  Developed by Arnaud Le Hors                                                *
  \*****************************************************************************/
@@ -198,9 +235,9 @@
  	for (i = 0, ext = extensions; i < nextensions; i++, ext++) {
  	    if (ext->name)
  		XpmFree(ext->name);
-diff -urN xc~/extras/Xpm/lib/CrBufFrI.c xc/extras/Xpm/lib/CrBufFrI.c
---- xc~/extras/Xpm/lib/CrBufFrI.c	2005-03-13 01:32:36.000000000 -0500
-+++ xc/extras/Xpm/lib/CrBufFrI.c	2005-03-13 01:34:39.000000000 -0500
+diff -urN xc/extras/Xpm/lib~/CrBufFrI.c xc/extras/Xpm/lib/CrBufFrI.c
+--- xc/extras/Xpm/lib~/CrBufFrI.c	2005-05-25 02:24:33.258307720 -0500
++++ xc/extras/Xpm/lib/CrBufFrI.c	2005-05-25 01:58:18.000000000 -0500
 @@ -31,6 +31,9 @@
  *                                                                             *
  *  Developed by Arnaud Le Hors                                                *
@@ -505,9 +542,9 @@
      if (info->hints_cmt)
  	size += 5 + strlen(info->hints_cmt);
  
-diff -urN xc~/extras/Xpm/lib/CrDatFrI.c xc/extras/Xpm/lib/CrDatFrI.c
---- xc~/extras/Xpm/lib/CrDatFrI.c	2005-03-13 01:32:36.000000000 -0500
-+++ xc/extras/Xpm/lib/CrDatFrI.c	2005-03-13 01:34:39.000000000 -0500
+diff -urN xc/extras/Xpm/lib~/CrDatFrI.c xc/extras/Xpm/lib/CrDatFrI.c
+--- xc/extras/Xpm/lib~/CrDatFrI.c	2005-05-25 02:24:33.260307725 -0500
++++ xc/extras/Xpm/lib/CrDatFrI.c	2005-05-25 01:58:18.000000000 -0500
 @@ -33,13 +33,16 @@
  \*****************************************************************************/
  /* $XFree86: xc/extras/Xpm/lib/CrDatFrI.c,v 1.2 2001/10/28 03:32:09 tsi Exp $ */
@@ -736,30 +773,9 @@
  	for (y = 0, line = ext->lines; y < b; y++, line++) {
  	    strcpy(*dataptr, *line);
  	    a++;
-diff -urN xc~/extras/Xpm/lib/Imakefile xc/extras/Xpm/lib/Imakefile
---- xc~/extras/Xpm/lib/Imakefile	2005-03-13 01:32:36.000000000 -0500
-+++ xc/extras/Xpm/lib/Imakefile	2005-03-13 01:34:39.000000000 -0500
-@@ -104,13 +104,15 @@
- 	 CrBufFrI.c CrDatFrP.c CrPFrBuf.c RdFToI.c WrFFrI.c \
- 	 CrBufFrP.c CrIFrBuf.c CrPFrDat.c RdFToP.c WrFFrP.c \
- 	 CrDatFrI.c CrIFrDat.c RdFToDat.c WrFFrDat.c \
--	 Attrib.c CrIFrP.c CrPFrI.c Image.c Info.c RdFToBuf.c WrFFrBuf.c
-+	 Attrib.c CrIFrP.c CrPFrI.c Image.c Info.c RdFToBuf.c WrFFrBuf.c \
-+	 s_popen.c
- 
-   OBJS = data.o create.o misc.o rgb.o scan.o parse.o hashtab.o \
- 	 CrBufFrI.o CrDatFrP.o CrPFrBuf.o RdFToI.o WrFFrI.o \
- 	 CrBufFrP.o CrIFrBuf.o CrPFrDat.o RdFToP.o WrFFrP.o \
- 	 CrDatFrI.o CrIFrDat.o RdFToDat.o WrFFrDat.o \
--	 Attrib.o CrIFrP.o CrPFrI.o Image.o Info.o RdFToBuf.o WrFFrBuf.o
-+	 Attrib.o CrIFrP.o CrPFrI.o Image.o Info.o RdFToBuf.o WrFFrBuf.o \
-+	 s_popen.o
- 
-        INCLUDES = -I.
-        LINTLIBS = $(LINTXTOLL) $(LINTXLIB) 
-diff -urN xc~/extras/Xpm/lib/RdFToBuf.c xc/extras/Xpm/lib/RdFToBuf.c
---- xc~/extras/Xpm/lib/RdFToBuf.c	2005-03-13 01:32:36.000000000 -0500
-+++ xc/extras/Xpm/lib/RdFToBuf.c	2005-03-13 01:34:39.000000000 -0500
+diff -urN xc/extras/Xpm/lib~/RdFToBuf.c xc/extras/Xpm/lib/RdFToBuf.c
+--- xc/extras/Xpm/lib~/RdFToBuf.c	2005-05-25 02:24:33.262307731 -0500
++++ xc/extras/Xpm/lib/RdFToBuf.c	2005-05-25 01:58:18.000000000 -0500
 @@ -37,6 +37,8 @@
   * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
   */
@@ -788,95 +804,240 @@
      ptr = (char *) XpmMalloc(len + 1);
      if (!ptr) {
  	fclose(fp);
-diff -urN xc~/extras/Xpm/lib/RdFToI.c xc/extras/Xpm/lib/RdFToI.c
---- xc~/extras/Xpm/lib/RdFToI.c	2005-03-13 01:32:36.000000000 -0500
-+++ xc/extras/Xpm/lib/RdFToI.c	2005-03-13 01:34:39.000000000 -0500
-@@ -33,6 +33,8 @@
+diff -urN xc/extras/Xpm/lib~/RdFToI.c xc/extras/Xpm/lib/RdFToI.c
+--- xc/extras/Xpm/lib~/RdFToI.c	2005-05-25 02:24:33.264307736 -0500
++++ xc/extras/Xpm/lib/RdFToI.c	2005-05-25 02:08:19.000000000 -0500
+@@ -33,16 +33,14 @@
  \*****************************************************************************/
  /* $XFree86: xc/extras/Xpm/lib/RdFToI.c,v 1.2 2001/10/28 03:32:09 tsi Exp $ */
  
 +/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
 +
  #include "XpmI.h"
- #include <sys/stat.h>
- #if !defined(NO_ZPIPE) && defined(WIN32)
-@@ -123,6 +125,12 @@
+-#include <sys/stat.h>
+-#if !defined(NO_ZPIPE) && defined(WIN32)
+-# define popen _popen
+-# define pclose _pclose
+-# if defined(STAT_ZFILE)
+-#  include <io.h>
+-#  define stat _stat
+-#  define fstat _fstat
+-# endif
++#ifndef NO_ZPIPE
++#include <fcntl.h>
++#include <errno.h>
++#include <sys/types.h>
++#include <sys/wait.h>
+ #endif
+ 
+ LFUNC(OpenReadFile, int, (char *filename, xpmData *mdata));
+@@ -120,6 +118,67 @@
+ }
+ #endif /* CXPMPROG */
+ 
++#ifndef NO_ZPIPE
++/* Do not depend on errno after read_through */
++FILE*
++xpmPipeThrough(fd, cmd, arg1, mode)
++    int fd;
++    const char* cmd;
++    const char* arg1;
++    const char* mode;
++{
++    FILE* fp;
++    int status, fds[2], in = 0, out = 1;
++    pid_t pid;
++    if ( 'w' == *mode )
++	out = 0, in = 1;
++    if ( pipe(fds) < 0 )
++	return NULL;
++    pid = fork();
++    if ( pid < 0 )
++	goto fail1;
++    if ( 0 == pid )
++    {
++	close(fds[in]);
++	if ( dup2(fds[out], out) < 0 )
++	    goto err;
++	close(fds[out]);
++	if ( dup2(fd, in) < 0 )
++	    goto err;
++	close(fd);
++	pid = fork();
++	if ( pid < 0 )
++	    goto err;
++	if ( 0 == pid )
++	{
++	    execlp(cmd, cmd, arg1, NULL);
++	    perror(cmd);
++	    goto err;
++	}
++	_exit(0);
++    err:
++	_exit(1);
++    }
++    close(fds[out]);
++    /* calling process: wait for first child */
++    while ( waitpid(pid, &status, 0) < 0 && EINTR == errno )
++	;
++    if ( WIFSIGNALED(status) ||
++	 (WIFEXITED(status) && WEXITSTATUS(status) != 0) )
++	goto fail2;
++    fp = fdopen(fds[in], mode);
++    if ( !fp )
++	goto fail2;
++    close(fd); /* still open in 2nd child */
++    return fp;
++fail1:
++    close(fds[out]);
++fail2:
++    close(fds[in]);
++    return NULL;
++}
++#endif
++
  /*
   * open the given file to be read as an xpmData which is returned.
   */
-+#ifndef NO_ZPIPE
-+	FILE *s_popen(char *cmd, const char *type);
-+#else
-+#	define s_popen popen
-+#endif
-+
- static int
- OpenReadFile(filename, mdata)
+@@ -128,72 +187,62 @@
      char *filename;
-@@ -141,17 +149,20 @@
+     xpmData *mdata;
+ {
+-#ifndef NO_ZPIPE
+-    char buf[BUFSIZ];
+-# ifdef STAT_ZFILE
+-    char *compressfile;
+-    struct stat status;
+-# endif
+-#endif
+-
+     if (!filename) {
+ 	mdata->stream.file = (stdin);
  	mdata->type = XPMFILE;
      } else {
- #ifndef NO_ZPIPE
+-#ifndef NO_ZPIPE
 -	int len = strlen(filename);
-+	size_t len = strlen(filename);
-+
-+	if (len == 0)
-+		return(XpmOpenFailed);
- 	if ((len > 2) && !strcmp(".Z", filename + (len - 2))) {
- 	    mdata->type = XPMPIPE;
+-	if ((len > 2) && !strcmp(".Z", filename + (len - 2))) {
+-	    mdata->type = XPMPIPE;
 -	    sprintf(buf, "uncompress -c \"%s\"", filename);
 -	    if (!(mdata->stream.file = popen(buf, "r")))
-+	    snprintf(buf, sizeof(buf), "uncompress -c \"%s\"", filename);
-+	    if (!(mdata->stream.file = s_popen(buf, "r")))
- 		return (XpmOpenFailed);
- 
- 	} else if ((len > 3) && !strcmp(".gz", filename + (len - 3))) {
- 	    mdata->type = XPMPIPE;
+-		return (XpmOpenFailed);
+-
+-	} else if ((len > 3) && !strcmp(".gz", filename + (len - 3))) {
+-	    mdata->type = XPMPIPE;
 -	    sprintf(buf, "gunzip -qc \"%s\"", filename);
 -	    if (!(mdata->stream.file = popen(buf, "r")))
-+	    snprintf(buf, sizeof(buf), "gunzip -qc \"%s\"", filename);
-+	    if (!(mdata->stream.file = s_popen(buf, "r")))
- 		return (XpmOpenFailed);
- 
- 	} else {
-@@ -159,19 +170,19 @@
- 	    if (!(compressfile = (char *) XpmMalloc(len + 4)))
+-		return (XpmOpenFailed);
+-
+-	} else {
+-# ifdef STAT_ZFILE
+-	    if (!(compressfile = (char *) XpmMalloc(len + 4)))
++	int fd = open(filename, O_RDONLY);
++#if defined(NO_ZPIPE)
++	if ( fd < 0 )
++	    return XpmOpenFailed;
++#else
++	const char* ext = NULL;
++	if ( fd >= 0 )
++	    ext = strrchr(filename, '.');
++#ifdef STAT_ZFILE /* searching for z-files if the given name not found */
++	else
++	{
++	    size_t len = strlen(filename);
++	    char *compressfile = (char *) XpmMalloc(len + 4);
++	    if ( !compressfile )
  		return (XpmNoMemory);
- 
+-
 -	    sprintf(compressfile, "%s.Z", filename);
-+	    snprintf(compressfile, len+4, "%s.Z", filename);
- 	    if (!stat(compressfile, &status)) {
+-	    if (!stat(compressfile, &status)) {
 -		sprintf(buf, "uncompress -c \"%s\"", compressfile);
 -		if (!(mdata->stream.file = popen(buf, "r"))) {
-+		snprintf(buf, sizeof(buf), "uncompress -c \"%s\"", compressfile);
-+		if (!(mdata->stream.file = s_popen(buf, "r"))) {
++	    strcpy(compressfile, filename);
++	    strcpy(compressfile + len, ext = ".Z");
++	    fd = open(compressfile, O_RDONLY);
++	    if ( fd < 0 )
++	    {
++		strcpy(compressfile + len, ext = ".gz");
++		fd = open(compressfile, O_RDONLY);
++		if ( fd < 0 )
++		{
  		    XpmFree(compressfile);
- 		    return (XpmOpenFailed);
- 		}
- 		mdata->type = XPMPIPE;
- 	    } else {
+-		    return (XpmOpenFailed);
+-		}
+-		mdata->type = XPMPIPE;
+-	    } else {
 -		sprintf(compressfile, "%s.gz", filename);
-+		snprintf(compressfile, len+4, "%s.gz", filename);
- 		if (!stat(compressfile, &status)) {
+-		if (!stat(compressfile, &status)) {
 -		    sprintf(buf, "gunzip -c \"%s\"", compressfile);
 -		    if (!(mdata->stream.file = popen(buf, "r"))) {
-+		    snprintf(buf, sizeof(buf), "gunzip -c \"%s\"", compressfile);
-+		    if (!(mdata->stream.file = s_popen(buf, "r"))) {
- 			XpmFree(compressfile);
- 			return (XpmOpenFailed);
- 		    }
-@@ -217,7 +228,7 @@
- 	break;
- #ifndef NO_ZPIPE
-     case XPMPIPE:
+-			XpmFree(compressfile);
+-			return (XpmOpenFailed);
+-		    }
+-		    mdata->type = XPMPIPE;
+-		} else {
+-# endif
+-#endif
+-		    if (!(mdata->stream.file = fopen(filename, "r"))) {
+-#if !defined(NO_ZPIPE) && defined(STAT_ZFILE)
+-			XpmFree(compressfile);
+-#endif
+-			return (XpmOpenFailed);
+-		    }
+-		    mdata->type = XPMFILE;
+-#ifndef NO_ZPIPE
+-# ifdef STAT_ZFILE
++		    return XpmOpenFailed;
+ 		}
+ 	    }
+ 	    XpmFree(compressfile);
+-# endif
+ 	}
+ #endif
++	if ( ext && !strcmp(ext, ".Z") )
++	{
++	    mdata->type = XPMPIPE;
++	    mdata->stream.file = xpmPipeThrough(fd, "uncompress", "-c", "r");
++	}
++	else if ( ext && !strcmp(ext, ".gz") )
++	{
++	    mdata->type = XPMPIPE;
++	    mdata->stream.file = xpmPipeThrough(fd, "gunzip", "-qc", "r");
++	}
++	else
++#endif /* z-files */
++	{
++	    mdata->type = XPMFILE;
++	    mdata->stream.file = fdopen(fd, "r");
++	}
++	if (!mdata->stream.file)
++	{
++	    close(fd);
++	    return (XpmOpenFailed);
++	}
+     }
+     mdata->CommentLength = 0;
+ #ifdef CXPMPROG
+@@ -210,15 +259,6 @@
+ xpmDataClose(mdata)
+     xpmData *mdata;
+ {
+-    switch (mdata->type) {
+-    case XPMFILE:
+-	if (mdata->stream.file != (stdin))
+-	    fclose(mdata->stream.file);
+-	break;
+-#ifndef NO_ZPIPE
+-    case XPMPIPE:
 -	pclose(mdata->stream.file);
+-	break;
+-#endif
+-    }
++    if (mdata->stream.file != (stdin))
 +	fclose(mdata->stream.file);
- 	break;
- #endif
-     }
-diff -urN xc~/extras/Xpm/lib/WrFFrBuf.c xc/extras/Xpm/lib/WrFFrBuf.c
---- xc~/extras/Xpm/lib/WrFFrBuf.c	2005-03-13 01:32:36.000000000 -0500
-+++ xc/extras/Xpm/lib/WrFFrBuf.c	2005-03-13 01:34:39.000000000 -0500
+ }
+diff -urN xc/extras/Xpm/lib~/WrFFrBuf.c xc/extras/Xpm/lib/WrFFrBuf.c
+--- xc/extras/Xpm/lib~/WrFFrBuf.c	2005-05-25 02:24:33.265307739 -0500
++++ xc/extras/Xpm/lib/WrFFrBuf.c	2005-05-25 01:58:18.000000000 -0500
 @@ -32,6 +32,8 @@
  *  Developed by Arnaud Le Hors                                                *
  \*****************************************************************************/
@@ -895,19 +1056,27 @@
  
      return XpmSuccess;
  }
-diff -urN xc~/extras/Xpm/lib/WrFFrI.c xc/extras/Xpm/lib/WrFFrI.c
---- xc~/extras/Xpm/lib/WrFFrI.c	2005-03-13 01:32:36.000000000 -0500
-+++ xc/extras/Xpm/lib/WrFFrI.c	2005-03-13 01:34:39.000000000 -0500
-@@ -38,6 +38,8 @@
-  * Lorens Younes (d93-hyo@nada.kth.se) 4/96
+diff -urN xc/extras/Xpm/lib~/WrFFrI.c xc/extras/Xpm/lib/WrFFrI.c
+--- xc/extras/Xpm/lib~/WrFFrI.c	2005-05-25 02:24:33.266307741 -0500
++++ xc/extras/Xpm/lib/WrFFrI.c	2005-05-25 02:15:16.000000000 -0500
+@@ -39,9 +39,13 @@
   */
  
-+/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+ #include "XpmI.h"
+-#if !defined(NO_ZPIPE) && defined(WIN32)
+-# define popen _popen
+-# define pclose _pclose
 +
- #include "XpmI.h"
- #if !defined(NO_ZPIPE) && defined(WIN32)
- # define popen _popen
-@@ -98,7 +100,7 @@
++#ifndef NO_ZPIPE
++#include "sys/wait.h"
++#include "sys/types.h"
++#include "fcntl.h"
++#include "unistd.h"
++#include "errno.h"
+ #endif
+ 
+ /* MS Windows define a function called WriteFile @#%#&!!! */
+@@ -98,7 +102,7 @@
      XpmInfo *info;
  {
      xpmData mdata;
@@ -916,85 +1085,115 @@
      int ErrorStatus;
  
      /* open file to write */
-@@ -121,7 +123,8 @@
+@@ -121,7 +125,8 @@
  #endif
  	/* let's try to make a valid C syntax name */
  	if (index(name, '.')) {
 -	    strcpy(new_name, name);
 +	    strncpy(new_name, name, sizeof(new_name));
-+	    new_name[sizeof(new_name)-1] = 0;
++	    new_name[sizeof(new_name)-1] = '\0';
  	    /* change '.' to '_' */
  	    name = s = new_name;
  	    while ((dot = index(s, '.'))) {
-@@ -131,7 +134,8 @@
- 	}
- 	if (index(name, '-')) {
- 	    if (name != new_name) {
--		strcpy(new_name, name);
-+		strncpy(new_name, name, sizeof(new_name));
-+		new_name[sizeof(new_name)-1] = 0;
- 		name = new_name;
- 	    }
- 	    /* change '-' to '_' */
-@@ -248,6 +252,8 @@
+@@ -248,6 +253,8 @@
      unsigned int x, y, h;
  
      h = height - 1;
-+    if (cpp != 0 && width >= (UINT_MAX - 3)/cpp)
++    if (cpp != 0 && width >= (UINT_MAX - 3)/cpp) 
 +	return XpmNoMemory;
      p = buf = (char *) XpmMalloc(width * cpp + 3);
      if (!buf)
  	return (XpmNoMemory);
-@@ -298,6 +304,11 @@
+@@ -295,6 +302,14 @@
+     fprintf(file, ",\n\"XPMENDEXT\"");
+ }
+ 
++
++#ifndef NO_ZPIPE
++FUNC(xpmPipeThrough, FILE*, (int fd,
++			     const char* cmd,
++			     const char* arg1,
++			     const char* mode));
++#endif
++
  /*
   * open the given file to be written as an xpmData which is returned
   */
-+#ifndef NO_ZPIPE
-+	FILE *s_popen(char *cmd, const char *type);
-+#else
-+#	define s_popen popen
-+#endif
- static int
- OpenWriteFile(filename, mdata)
+@@ -303,38 +318,32 @@
      char *filename;
-@@ -313,16 +324,20 @@
+     xpmData *mdata;
+ {
+-#ifndef NO_ZPIPE
+-    char buf[BUFSIZ];
+-
+-#endif
+-
+     if (!filename) {
+ 	mdata->stream.file = (stdout);
  	mdata->type = XPMFILE;
      } else {
  #ifndef NO_ZPIPE
 -	int len = strlen(filename);
-+	size_t len = strlen(filename);
-+
-+	if (len == 0)
-+		return(XpmOpenFailed);
-+
++	size_t len;
++#endif
++	int fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644);
++	if ( fd < 0 )
++	    return(XpmOpenFailed);
++#ifndef NO_ZPIPE
++	len = strlen(filename);
  	if (len > 2 && !strcmp(".Z", filename + (len - 2))) {
 -	    sprintf(buf, "compress > \"%s\"", filename);
 -	    if (!(mdata->stream.file = popen(buf, "w")))
-+	    snprintf(buf, sizeof(buf), "compress > \"%s\"", filename);
-+	    if (!(mdata->stream.file = s_popen(buf, "w")))
- 		return (XpmOpenFailed);
- 
+-		return (XpmOpenFailed);
+-
++	    mdata->stream.file = xpmPipeThrough(fd, "compress", NULL, "w");
  	    mdata->type = XPMPIPE;
  	} else if (len > 3 && !strcmp(".gz", filename + (len - 3))) {
 -	    sprintf(buf, "gzip -q > \"%s\"", filename);
 -	    if (!(mdata->stream.file = popen(buf, "w")))
-+	    snprintf(buf, sizeof(buf), "gzip -q > \"%s\"", filename);
-+	    if (!(mdata->stream.file = s_popen(buf, "w")))
- 		return (XpmOpenFailed);
- 
+-		return (XpmOpenFailed);
+-
++	    mdata->stream.file = xpmPipeThrough(fd, "gzip", "-q", "w");
  	    mdata->type = XPMPIPE;
-@@ -353,7 +368,7 @@
- 	break;
- #ifndef NO_ZPIPE
-     case XPMPIPE:
+-	} else {
++	} else
+ #endif
+-	    if (!(mdata->stream.file = fopen(filename, "w")))
+-		return (XpmOpenFailed);
+-
++	{
++	    mdata->stream.file = fdopen(fd, "w");
+ 	    mdata->type = XPMFILE;
+-#ifndef NO_ZPIPE
+ 	}
+-#endif
++	if (!mdata->stream.file)
++	    return (XpmOpenFailed);
+     }
+     return (XpmSuccess);
+ }
+@@ -346,15 +355,7 @@
+ xpmDataClose(mdata)
+     xpmData *mdata;
+ {
+-    switch (mdata->type) {
+-    case XPMFILE:
+-	if (mdata->stream.file != (stdout))
+-	    fclose(mdata->stream.file);
+-	break;
+-#ifndef NO_ZPIPE
+-    case XPMPIPE:
 -	pclose(mdata->stream.file);
+-	break;
+-#endif
+-    }
++    if (mdata->stream.file != (stdout))
 +	fclose(mdata->stream.file);
- 	break;
- #endif
-     }
-diff -urN xc~/extras/Xpm/lib/XpmI.h xc/extras/Xpm/lib/XpmI.h
---- xc~/extras/Xpm/lib/XpmI.h	2005-03-13 01:32:36.000000000 -0500
-+++ xc/extras/Xpm/lib/XpmI.h	2005-03-13 01:34:39.000000000 -0500
+ }
++
+diff -urN xc/extras/Xpm/lib~/XpmI.h xc/extras/Xpm/lib/XpmI.h
+--- xc/extras/Xpm/lib~/XpmI.h	2005-05-25 02:24:33.267307744 -0500
++++ xc/extras/Xpm/lib/XpmI.h	2005-05-25 01:58:18.000000000 -0500
 @@ -49,8 +49,10 @@
   * lets try to solve include files
   */
@@ -1038,9 +1237,9 @@
      xpmHashAtom *atomTable;
  }      xpmHashTable;
  
-diff -urN xc~/extras/Xpm/lib/create.c xc/extras/Xpm/lib/create.c
---- xc~/extras/Xpm/lib/create.c	2005-03-13 01:32:36.000000000 -0500
-+++ xc/extras/Xpm/lib/create.c	2005-03-13 01:39:04.000000000 -0500
+diff -urN xc/extras/Xpm/lib~/create.c xc/extras/Xpm/lib/create.c
+--- xc/extras/Xpm/lib~/create.c	2005-05-25 02:24:33.272307757 -0500
++++ xc/extras/Xpm/lib/create.c	2005-05-25 01:58:18.000000000 -0500
 @@ -1,3 +1,4 @@
 +/* $XdotOrg: pre-CVS proposed fix for CESA-2004-003 alanc 7/25/2004 $ */
  /*
@@ -1391,9 +1590,9 @@
  	    buf[cpp] = '\0';
  	    if (USE_HASHTABLE) {
  		xpmHashAtom *slot;
-diff -urN xc~/extras/Xpm/lib/data.c xc/extras/Xpm/lib/data.c
---- xc~/extras/Xpm/lib/data.c	2005-03-13 01:32:36.000000000 -0500
-+++ xc/extras/Xpm/lib/data.c	2005-03-13 01:34:39.000000000 -0500
+diff -urN xc/extras/Xpm/lib~/data.c xc/extras/Xpm/lib/data.c
+--- xc/extras/Xpm/lib~/data.c	2005-05-25 02:24:33.274307762 -0500
++++ xc/extras/Xpm/lib/data.c	2005-05-25 01:58:18.000000000 -0500
 @@ -33,6 +33,8 @@
  \*****************************************************************************/
  /* $XFree86: xc/extras/Xpm/lib/data.c,v 1.4 2002/01/07 19:40:49 dawes Exp $ */
@@ -1433,9 +1632,9 @@
      int l, n = 0;
  
      if (data->type) {
-diff -urN xc~/extras/Xpm/lib/hashtab.c xc/extras/Xpm/lib/hashtab.c
---- xc~/extras/Xpm/lib/hashtab.c	2005-03-13 01:32:36.000000000 -0500
-+++ xc/extras/Xpm/lib/hashtab.c	2005-03-13 01:34:39.000000000 -0500
+diff -urN xc/extras/Xpm/lib~/hashtab.c xc/extras/Xpm/lib/hashtab.c
+--- xc/extras/Xpm/lib~/hashtab.c	2005-05-25 02:24:33.275307765 -0500
++++ xc/extras/Xpm/lib/hashtab.c	2005-05-25 01:58:18.000000000 -0500
 @@ -135,15 +135,17 @@
      xpmHashTable *table;
  {
@@ -1465,9 +1664,9 @@
      atomTable = (xpmHashAtom *) XpmMalloc(table->size * sizeof(*atomTable));
      if (!atomTable)
  	return (XpmNoMemory);
-diff -urN xc~/extras/Xpm/lib/misc.c xc/extras/Xpm/lib/misc.c
---- xc~/extras/Xpm/lib/misc.c	2005-03-13 01:32:36.000000000 -0500
-+++ xc/extras/Xpm/lib/misc.c	2005-03-13 01:34:39.000000000 -0500
+diff -urN xc/extras/Xpm/lib~/misc.c xc/extras/Xpm/lib/misc.c
+--- xc/extras/Xpm/lib~/misc.c	2005-05-25 02:24:33.276307767 -0500
++++ xc/extras/Xpm/lib/misc.c	2005-05-25 01:58:18.000000000 -0500
 @@ -44,7 +44,7 @@
      char *s1;
  {
@@ -1477,9 +1676,9 @@
  
      if (s2 = (char *) XpmMalloc(l))
  	strcpy(s2, s1);
-diff -urN xc~/extras/Xpm/lib/parse.c xc/extras/Xpm/lib/parse.c
---- xc~/extras/Xpm/lib/parse.c	2005-03-13 01:32:36.000000000 -0500
-+++ xc/extras/Xpm/lib/parse.c	2005-03-13 01:34:39.000000000 -0500
+diff -urN xc/extras/Xpm/lib~/parse.c xc/extras/Xpm/lib/parse.c
+--- xc/extras/Xpm/lib~/parse.c	2005-05-25 02:24:33.278307772 -0500
++++ xc/extras/Xpm/lib/parse.c	2005-05-25 01:58:18.000000000 -0500
 @@ -1,3 +1,4 @@
 +/* $XdotOrg: pre-CVS proposed fix for CESA-2004-003 alanc 7/25/2004 $ */
  /*
@@ -1751,194 +1950,9 @@
  
  /*
   * This function parses an Xpm file or data and store the found informations
-diff -urN xc~/extras/Xpm/lib/s_popen.c xc/extras/Xpm/lib/s_popen.c
---- xc~/extras/Xpm/lib/s_popen.c	1969-12-31 19:00:00.000000000 -0500
-+++ xc/extras/Xpm/lib/s_popen.c	2005-03-13 01:34:39.000000000 -0500
-@@ -0,0 +1,181 @@
-+/*
-+ * Copyright (C) 2004 The X.Org fundation
-+ * 
-+ * Permission is hereby granted, free of charge, to any person
-+ * obtaining a copy of this software and associated documentation
-+ * files (the "Software"), to deal in the Software without
-+ * restriction, including without limitation the rights to use, copy,
-+ * modify, merge, publish, distribute, sublicense, and/or sell copies
-+ * of the Software, and to permit persons to whom the Software is fur-
-+ * nished to do so, subject to the following conditions:
-+ * 
-+ * The above copyright notice and this permission notice shall be
-+ * included in all copies or substantial portions of the Software.
-+ * 
-+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-+ * NONINFRINGEMENT.  IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR
-+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
-+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-+ * 
-+ * Except as contained in this notice, the name of the X.Org fundation
-+ * shall not be used in advertising or otherwise to promote the sale,
-+ * use or other dealings in this Software without prior written
-+ * authorization from the X.Org fundation.
-+ */
-+
-+/*
-+** This is a secure but NOT 100% compatible replacement for popen()
-+** Note:        - don't use pclose() use fclose() for closing the returned
-+**                filedesc.!!!
-+**
-+** Known Bugs:  - unable to use i/o-redirection like > or <
-+** Author:      - Thomas Biege <thomas@suse.de>
-+** Credits:     - Andreas Pfaller <a.pfaller@pop.gun.de> for fixing a SEGV when
-+**                calling strtok()
-+*/
-+
-+#include <sys/types.h>
-+#include <sys/wait.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include <string.h>
-+
-+#define __SEC_POPEN_TOKEN " "
-+
-+FILE *s_popen(char *cmd, const char *type)
-+{
-+  pid_t pid;
-+  int pfd[2];
-+  int rpipe = 0, wpipe = 0, i;
-+  char **argv;
-+  char *ptr;
-+  char *cmdcpy;
-+
-+
-+  if(cmd == NULL || cmd == "")
-+    return(NULL);
-+
-+  if(type[0] != 'r' && type[0] != 'w')
-+    return(NULL);
-+
-+  if ((cmdcpy = strdup(cmd)) == NULL)
-+    return(NULL);
-+
-+  argv = NULL;
-+  if( (ptr = strtok(cmdcpy, __SEC_POPEN_TOKEN)) == NULL)
-+  {
-+    free(cmdcpy);
-+    return(NULL);
-+  }
-+
-+  for(i = 0;; i++)
-+  {
-+    if( ( argv = (char **) realloc(argv, (i+1) * sizeof(char *)) ) == NULL)
-+    {
-+      free(cmdcpy);
-+      return(NULL);
-+    }
-+
-+    if( (*(argv+i) = (char *) malloc((strlen(ptr)+1) * sizeof(char))) == NULL)
-+    {
-+      free(cmdcpy);
-+      return(NULL);
-+    }
-+
-+    strcpy(argv[i], ptr);
-+
-+    if( (ptr = strtok(NULL, __SEC_POPEN_TOKEN)) == NULL)
-+    {
-+      if( ( argv = (char **) realloc(argv, (i+2) * sizeof(char *))) == NULL)
-+      {
-+        free(cmdcpy);
-+        return(NULL);
-+      }
-+      argv[i+1] = NULL;
-+      break;
-+    }
-+  }
-+
-+
-+  if(type[0] == 'r')
-+    rpipe = 1;
-+  else
-+    wpipe = 1;
-+
-+  if (pipe(pfd) < 0)
-+  {
-+    free(cmdcpy);
-+    return(NULL);
-+  }
-+
-+	if((pid = fork()) < 0)
-+  {
-+    close(pfd[0]);
-+    close(pfd[1]);
-+    free(cmdcpy);
-+    return(NULL);
-+  }
-+
-+	if(pid == 0)    /* child */
-+  {
-+    if((pid = fork()) < 0)
-+    {
-+      close(pfd[0]);
-+      close(pfd[1]);
-+      free(cmdcpy);
-+      return(NULL);
-+    }
-+    if(pid > 0)
-+    {
-+      exit(0);  /* child nr. 1 exits */
-+    }
-+
-+    /* child nr. 2 */
-+    if(rpipe)
-+    {
-+      close(pfd[0]);  /* close reading end, we don't need it */
-+      dup2(STDOUT_FILENO, STDERR_FILENO);
-+      if (pfd[1] != STDOUT_FILENO)
-+        dup2(pfd[1], STDOUT_FILENO);  /* redirect stdout to writing end of pipe */
-+    }
-+    else
-+    {
-+      close(pfd[1]);  /* close writing end, we don't need it */
-+      if (pfd[0] != STDIN_FILENO)
-+        dup2(pfd[0], STDIN_FILENO);    /* redirect stdin to reading end of pipe */
-+	  }
-+
-+    if(strchr(argv[0], '/') == NULL)
-+      execvp(argv[0], argv);  /* search in $PATH */
-+    else
-+      execv(argv[0], argv);
-+
-+    close(pfd[0]);
-+    close(pfd[1]);
-+    free(cmdcpy);
-+    return(NULL);  /* exec failed.. ooops! */
-+  }
-+  else          /* parent */
-+  {
-+    waitpid(pid, NULL, 0); /* wait for child nr. 1 */
-+
-+    if(rpipe)
-+    {
-+      close(pfd[1]);
-+      free(cmdcpy);
-+      return(fdopen(pfd[0], "r"));
-+    }
-+    else
-+    {
-+      close(pfd[0]);
-+      free(cmdcpy);
-+      return(fdopen(pfd[1], "w"));
-+    }
-+
-+  }
-+}
-+
-diff -urN xc~/extras/Xpm/lib/scan.c xc/extras/Xpm/lib/scan.c
---- xc~/extras/Xpm/lib/scan.c	2005-03-13 01:32:36.000000000 -0500
-+++ xc/extras/Xpm/lib/scan.c	2005-03-13 01:39:04.000000000 -0500
+diff -urN xc/extras/Xpm/lib~/scan.c xc/extras/Xpm/lib/scan.c
+--- xc/extras/Xpm/lib~/scan.c	2005-05-25 02:24:33.286307793 -0500
++++ xc/extras/Xpm/lib/scan.c	2005-05-25 01:58:18.000000000 -0500
 @@ -43,6 +43,8 @@
   * Lorens Younes (d93-hyo@nada.kth.se) 4/96
   */
@@ -2120,9 +2134,8 @@
  }
  
  #undef CLEAN_UP
-diff -urN xc~/lib/Xpm/Imakefile xc/lib/Xpm/Imakefile
---- xc~/lib/Xpm/Imakefile	2005-03-13 01:32:36.000000000 -0500
-+++ xc/lib/Xpm/Imakefile	2005-03-13 01:34:39.000000000 -0500
+--- xc/lib/Xpm/Imakefile~	2005-05-25 02:54:50.045583246 -0500
++++ xc/lib/Xpm/Imakefile	2005-05-25 02:55:18.377736639 -0500
 @@ -42,11 +42,24 @@
  SPRINTFDEF = -DVOID_SPRINTF
  #endif
@@ -2155,7 +2168,7 @@
  	 CrDatFrI.c CrIFrDat.c RdFToDat.c WrFFrDat.c \
 -	 Attrib.c CrIFrP.c CrPFrI.c Image.c Info.c RdFToBuf.c WrFFrBuf.c
 +	 Attrib.c CrIFrP.c CrPFrI.c Image.c Info.c RdFToBuf.c WrFFrBuf.c \
-+	 s_popen.c $(SNPRINTFSRCS)
++	 $(SNPRINTFSRCS)
  
    OBJS = data.o create.o misc.o rgb.o scan.o parse.o hashtab.o \
  	 CrBufFrI.o CrDatFrP.o CrPFrBuf.o RdFToI.o WrFFrI.o \
@@ -2163,18 +2176,16 @@
  	 CrDatFrI.o CrIFrDat.o RdFToDat.o WrFFrDat.o \
 -	 Attrib.o CrIFrP.o CrPFrI.o Image.o Info.o RdFToBuf.o WrFFrBuf.o
 +	 Attrib.o CrIFrP.o CrPFrI.o Image.o Info.o RdFToBuf.o WrFFrBuf.o \
-+	 s_popen.o $(SNPRINTFOBJS)
++	 $(SNPRINTFOBJS)
  
           XPMDIR = $(TOP)/extras/Xpm
        XPMLIBDIR = $(TOP)/extras/Xpm/lib
-@@ -99,5 +114,10 @@
- LinkSourceFile(RdFToBuf.c,$(XPMLIBDIR))
+@@ -100,4 +115,8 @@
  LinkSourceFile(WrFFrBuf.c,$(XPMLIBDIR))
  LinkSourceFile(xpm.h,$(XPMLIBDIR))
-+LinkSourceFile(s_popen.c,$(XPMLIBDIR))
-+
+ 
 +#if !HasSnprintf
 +LinkSourceFile(snprintf.c,$(LIBSRC)/misc)
 +#endif
- 
++
  DependTarget()



Reply to: