See attached.
In case of too many mail/BTS/web gateways, I posted a backup copy at
http://recycle.lbl.gov/~ldoolitt/087a_SECURITY_libXpm_vulnerabilities.diff
When I say "tested" I mean tested in isolation.
My attempts to fully test the debian build process
have so far failed, for (I think) unrelated reasons.
apt-src and I are not friends yet.
- Larry
Candidate response to debian bug #308783, based on
http://ftp.x.org/pub/X11R6.8.1/patches/X11R6.8.1-to-X11R6.8.2.patch.gz
This patch is to be applied _after_
$ md5sum 087_SECURITY_libXpm_vulnerabilities.diff
810923ff9eac7eb83d96870a4fbaab15 087_SECURITY_libXpm_vulnerabilities.diff
Other than sorting out the patch basis and removing fuzz, my only contribution
is to remove a compilation warning caused by a missing FUNC(xpmPipeThrough, ...)
in RdFToI.c. Verified against the full X11R6.8.2 sources: the only
other differences are CVS tags and some trailing spaces in the source.
Tested, works. 2005-05-23 Larry Doolittle <ldoolitt@recycle.lbl.gov>
diff -ur xc~/extras/Xpm/lib/RdFToI.c xc/extras/Xpm/lib/RdFToI.c
--- xc~/extras/Xpm/lib/RdFToI.c 2005-05-23 10:12:01.211131000 -0700
+++ xc/extras/Xpm/lib/RdFToI.c 2005-05-23 10:22:48.159031812 -0700
@@ -36,15 +36,11 @@
/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
#include "XpmI.h"
-#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));
@@ -122,89 +118,132 @@
}
#endif /* CXPMPROG */
-/*
- * 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
+/* Do not depend on errno after read_through */
+FUNC(xpmPipeThrough, FILE*, (int fd, const char* cmd, const char* arg1, const char* mode));
+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.
+ */
static int
OpenReadFile(filename, mdata)
char *filename;
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
- size_t len = strlen(filename);
-
- if (len == 0)
- return(XpmOpenFailed);
- if ((len > 2) && !strcmp(".Z", filename + (len - 2))) {
- mdata->type = XPMPIPE;
- 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;
- snprintf(buf, sizeof(buf), "gunzip -qc \"%s\"", filename);
- if (!(mdata->stream.file = s_popen(buf, "r")))
- 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);
-
- snprintf(compressfile, len+4, "%s.Z", filename);
- if (!stat(compressfile, &status)) {
- 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 {
- snprintf(compressfile, len+4, "%s.gz", filename);
- if (!stat(compressfile, &status)) {
- snprintf(buf, sizeof(buf), "gunzip -c \"%s\"", compressfile);
- if (!(mdata->stream.file = s_popen(buf, "r"))) {
- 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
@@ -221,15 +260,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:
+ if (mdata->stream.file != (stdin))
fclose(mdata->stream.file);
- break;
-#endif
- }
}
diff -ur xc~/extras/Xpm/lib/WrFFrI.c xc/extras/Xpm/lib/WrFFrI.c
--- xc~/extras/Xpm/lib/WrFFrI.c 2005-05-23 09:28:21.000000000 -0700
+++ xc/extras/Xpm/lib/WrFFrI.c 2005-05-23 10:20:24.000366045 -0700
@@ -38,12 +38,14 @@
* Lorens Younes (d93-hyo@nada.kth.se) 4/96
*/
-/* 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
+
+#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 @#%#&!!! */
@@ -124,7 +126,7 @@
/* let's try to make a valid C syntax name */
if (index(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, '.'))) {
@@ -134,8 +136,7 @@
}
if (index(name, '-')) {
if (name != new_name) {
- strncpy(new_name, name, sizeof(new_name));
- new_name[sizeof(new_name)-1] = 0;
+ strcpy(new_name, name);
name = new_name;
}
/* change '-' to '_' */
@@ -301,55 +302,48 @@
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)
char *filename;
xpmData *mdata;
{
-#ifndef NO_ZPIPE
- char buf[BUFSIZ];
-
-#endif
-
if (!filename) {
mdata->stream.file = (stdout);
mdata->type = XPMFILE;
} else {
#ifndef NO_ZPIPE
- 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))) {
- snprintf(buf, sizeof(buf), "compress > \"%s\"", filename);
- if (!(mdata->stream.file = s_popen(buf, "w")))
- return (XpmOpenFailed);
-
+ mdata->stream.file = xpmPipeThrough(fd, "compress", NULL, "w");
mdata->type = XPMPIPE;
} else if (len > 3 && !strcmp(".gz", filename + (len - 3))) {
- snprintf(buf, sizeof(buf), "gzip -q > \"%s\"", filename);
- if (!(mdata->stream.file = s_popen(buf, "w")))
- return (XpmOpenFailed);
-
+ mdata->stream.file = xpmPipeThrough(fd, "gzip", "-q", "w");
mdata->type = 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);
}
@@ -361,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:
+ if (mdata->stream.file != (stdout))
fclose(mdata->stream.file);
- break;
-#endif
- }
}
+
Attachment:
signature.asc
Description: Digital signature