temp file creation problem in inn

Greg KH greg at wirex.com
Fri Dec 29 18:45:33 UTC 2000



Hi,

In building Immunix Linux 7.0, we ran across the following problem in
inn version 2.2.3:

In an number of different places, temp files are created in an insecure
way.  The patch below, by Steve Beattie <steve at wirex.com> should fix
this problem on Linux, but since inn is a cross platform program, it
will not work on systems that do not have the mkstemp function.

thanks,

greg k-h


diff -ur inn-2.2.3-orig/backends/innxmit.c inn-2.2.3/backends/innxmit.c
--- inn-2.2.3-orig/backends/innxmit.c	Tue Jul 18 16:54:07 2000
+++ inn-2.2.3/backends/innxmit.c	Mon Dec 18 20:30:44 2000
@@ -522,10 +522,11 @@
     char	*Article;
     char	*MessageID;
 {
+    int		tmpfd;
     /* Temp file already open? */
     if (BATCHfp == NULL) {
-	(void)mktemp(BATCHtemp);
-	if ((BATCHfp = fopen(BATCHtemp, "w")) == NULL) {
+	if ((tmpfd = mkstemp(BATCHtemp)) == -1 ||
+	    (BATCHfp = fdopen(tmpfd, "w")) == NULL) {
 	    (void)fprintf(stderr, "Can't open \"%s\", %s\n",
 		    BATCHtemp, strerror(errno));
 	    ExitWithStats(1);
diff -ur inn-2.2.3-orig/backends/nntpget.c inn-2.2.3/backends/nntpget.c
--- inn-2.2.3-orig/backends/nntpget.c	Tue Jul 18 16:54:07 2000
+++ inn-2.2.3/backends/nntpget.c	Mon Dec 18 20:30:44 2000
@@ -313,6 +313,7 @@
 	    Usage("No -d or -n when reading stdin");
     }
     else {
+	int tmpfd;
 	/* Ask the server for a list of what's new. */
 	if (Groups == NULL)
 	    Groups = "*";
@@ -335,8 +336,7 @@
 
 	/* Create a temporary file. */
 	(void)sprintf(temp, "%s/nntpgetXXXXXX", innconf->pathtmp);
-	(void)mktemp(temp);
-	if ((F = fopen(temp, "w+")) == NULL) {
+	if ((tmpfd = mkstemp(temp)) == -1 || (F = fopen(temp, "w+")) == NULL) {
 	    (void)fprintf(stderr, "Can't open \"%s\", %s\n",
 		    temp, strerror(errno));
 	    exit(1);
diff -ur inn-2.2.3-orig/expire/makehistory.c inn-2.2.3/expire/makehistory.c
--- inn-2.2.3-orig/expire/makehistory.c	Tue Jul 18 16:54:07 2000
+++ inn-2.2.3/expire/makehistory.c	Mon Dec 18 20:31:19 2000
@@ -1435,6 +1435,7 @@
     char		*oldtemp;
     ARTHANDLE		*art = (ARTHANDLE *)NULL;
     FILE		*index = (FILE *)NULL;
+    FILE 		*tmpF;
 
     /* First thing, set up logging and our identity. */
     openlog("makehistory", L_OPENLOG_FLAGS | LOG_PID, LOG_INN_PROG);     
@@ -1594,13 +1595,6 @@
     /* Open history file. */
     xchdir(HISTORYDIR);
 
-    if (Update || !Overwrite) {
-	(void)sprintf(temp, "%s/histXXXXXX", tmpdir);
-	(void)mktemp(temp);
-	TempTextFile = oldtemp ? COPY(oldtemp) : COPY(temp);
-    }
-    else
-	TempTextFile = NULL;
     if (Update) {
 	if (ICCopen() < 0) {
 	    (void)fprintf(stderr, "Can't talk to server, %s\n",
@@ -1621,7 +1615,21 @@
 	}
     }
 
-    if (!Nowrite && (out = fopen(TempTextFile ? TempTextFile : TextFile, mode)) == NULL) {
+    if (Update || !Overwrite) {
+	if (oldtemp) {
+	    TempTextFile = COPY(oldtemp);
+	    tmpF =  fopen(TempTextFile, mode);
+	}
+	else {
+	    (void)sprintf(temp, "%s/histXXXXXX", tmpdir);
+	    TempTextFile = COPY(temp);
+	    tmpF = fdopen(mkstemp(TempTextFile), mode);
+	}
+    }
+    else
+	TempTextFile = NULL;
+
+    if (!Nowrite && (out = (TempTextFile ? tmpF : fopen(TextFile, mode))) == NULL) {
 	(void)fprintf(stderr, "Can't write to history file, %s\n",
 		strerror(errno));
 	exit(1);
diff -ur inn-2.2.3-orig/frontends/inews.c inn-2.2.3/frontends/inews.c
--- inn-2.2.3-orig/frontends/inews.c	Tue Jul 18 16:54:07 2000
+++ inn-2.2.3/frontends/inews.c	Mon Dec 18 20:30:44 2000
@@ -1149,7 +1149,7 @@
      || (F = xfopena(deadfile)) == NULL) {
 	TempName(innconf->pathtmp, temp);
 	(void)umask(0);
-	if ((i = open(temp, O_WRONLY | O_CREAT, BATCHFILE_MODE)) < 0
+	if ((i = open(temp, O_WRONLY | O_CREAT | O_EXCL, BATCHFILE_MODE)) < 0
 	 || (F = fdopen(i, "w")) == NULL)
 	    PerrorExit(FALSE, "Can't create spool file");
 	deadfile = NULL;
diff -ur inn-2.2.3-orig/frontends/rnews.c inn-2.2.3/frontends/rnews.c
--- inn-2.2.3-orig/frontends/rnews.c	Tue Jul 18 16:54:07 2000
+++ inn-2.2.3/frontends/rnews.c	Mon Dec 18 20:30:44 2000
@@ -714,7 +714,7 @@
     strcat(temp, "/.");
     strcat(temp, ++p);
     (void)umask(0);
-    if ((spfd = open(temp, O_WRONLY | O_CREAT, BATCHFILE_MODE)) < 0) {
+    if ((spfd = open(temp, O_WRONLY | O_CREAT | O_EXCL, BATCHFILE_MODE)) < 0) {
 	syslog(L_FATAL, "cant open %s %m", temp);
 	exit(1);
     }
diff -ur inn-2.2.3-orig/innfeed/misc.c inn-2.2.3/innfeed/misc.c
--- inn-2.2.3-orig/innfeed/misc.c	Tue Jul 18 16:54:07 2000
+++ inn-2.2.3/innfeed/misc.c	Mon Dec 18 20:30:44 2000
@@ -784,22 +784,21 @@
   FILE *tmpFp ;
   int c ;
   int i ;
-
-  tmpname = malloc (pathMax(NULL) + 1) ;
-  sprintf (tmpname,"%s.XXXXXX",name) ;
-  mktemp (tmpname) ;
+  int tmpfd ;
 
   if (currlen <= size)
     {
-      FREE(tmpname) ;
-      
       d_printf (1,"No need to shrink file (%s %ld vs %ld\n",
                name,size,currlen) ;
       return true ;
     }
 
+  tmpname = malloc (pathMax(NULL) + 1) ;
+  sprintf (tmpname,"%s.XXXXXX",name) ;
+
   /* create a temp file that will go away when closed. */
-  if ((tmpFp = fopen (tmpname,"w")) == NULL)
+  if ((tmpfd = mkstemp (tmpname)) == -1 ||
+      (tmpFp = fdopen (tmpfd,"w")) == NULL)
     {
       syslog (LOG_ERR,SHRINK_TEMP_OPEN,tmpname) ;
       FREE (tmpname) ;
diff -ur inn-2.2.3-orig/lib/clientactive.c inn-2.2.3/lib/clientactive.c
--- inn-2.2.3-orig/lib/clientactive.c	Tue Jul 18 16:54:07 2000
+++ inn-2.2.3/lib/clientactive.c	Mon Dec 18 20:30:44 2000
@@ -3,6 +3,7 @@
 */
 #include <stdio.h>
 #include <sys/types.h>
+#include <fcntl.h>
 #include "configdata.h"
 #include "clibrary.h"
 #include <errno.h>
@@ -43,9 +44,14 @@
     char	*p;
     int		oerrno;
     FILE	*F;
+    int		tmpfd;
 
     (void)unlink(pathname);
-    if ((F = fopen(pathname, "w")) == NULL)
+
+    if ((tmpfd = open (pathname, O_WRONLY | O_CREAT | O_EXCL, S_IRWXU) == -1))
+	return NULL;
+
+    if ((F = fdopen(tmpfd, "w")) == NULL)
 	return NULL;
 
     /* Send a LIST command to and capture the output. */

-- 
greg@(kroah|wirex).com
http://immunix.org/~greg



More information about the inn-bugs mailing list