summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTopi Miettinen <Topi.Miettinen@nic.fi>2000-10-17 20:30:00 +0300
committerMiquel van Smoorenburg <miquels@debian.org>2016-11-11 07:07:17 -0800
commit9f2e9d20f0bbf50a57071ed4e7ed8c364d654cfd (patch)
tree1cf400866d8b27f56c512b383050f93efc6eb2e0
parent498615b922d85f05775e13646dddd0697bc77c31 (diff)
Bug#74976: elvis-tiny: temporary file problems
Package: elvis-tiny Version: 1.4-9 Severity: grave Elvis-tiny (probably full elvis also) has serious problems with temporary file use. Those files are created with a predictable pattern and O_EXCL flag is not used when opening. This makes elvis users vulnerable to race conditions and/or data lossage. ======================================================================= Topi included a patch to fix these problems, but the patch itself was broken in 2 ways: 1. Recovery of lost files didn't work anymore 2. :w to an existing file broke. The patch below by Miquel van Smoorenburg, based on Topi's bugreport and patch, should fix the bug without any side effects. Gbp-Pq: Name patch-tempfile.diff
-rw-r--r--Makefile.mix3
-rw-r--r--cmd1.c16
-rw-r--r--system.c17
-rw-r--r--tmp.c27
4 files changed, 55 insertions, 8 deletions
diff --git a/Makefile.mix b/Makefile.mix
index dad3dfc..38f2774 100644
--- a/Makefile.mix
+++ b/Makefile.mix
@@ -45,7 +45,8 @@ LIBS= -ltinfo
BIN= /usr/bin
CFLAGS= -O2 -DM_SYSV -DCRUNCH -DNO_MKEXRC -DNO_CURSORSHAPE -DNO_CHARATTR \
-DNO_SHOWMODE -DNO_MODELINE -DNO_OPTCOLS -DNO_DIGRAPH -DNO_ABBR \
- -DNO_AT -DNO_SENTENCE -DNO_ERRLIST -fsigned-char $(EXTRA_CFLAGS)
+ -DNO_AT -DNO_SENTENCE -DNO_ERRLIST -DUSE_MKSTEMP -DUSE_SNPRINTF \
+ -fsigned-char $(EXTRA_CFLAGS)
OF= -o
RF= -c
DATE= -DDATE=\'\"`date`\"\'
diff --git a/cmd1.c b/cmd1.c
index dd7ef77..519308f 100644
--- a/cmd1.c
+++ b/cmd1.c
@@ -158,6 +158,8 @@ void cmd_mark(frommark, tomark, cmd, bang, extra)
mark[*extra - 'a'] = tomark;
}
+void cmd_write2(MARK frommark, MARK tomark, int fd);
+
/*ARGSUSED*/
void cmd_write(frommark, tomark, cmd, bang, extra)
MARK frommark;
@@ -168,9 +170,6 @@ void cmd_write(frommark, tomark, cmd, bang, extra)
{
int fd;
int append; /* boolean: write in "append" mode? */
- REG long l;
- REG char *scan;
- REG int i;
/* if all lines are to be written, use tmpsave() */
if (frommark == MARK_FIRST && tomark == MARK_LAST)
@@ -221,6 +220,16 @@ void cmd_write(frommark, tomark, cmd, bang, extra)
return;
}
}
+ cmd_write2(frommark, tomark, fd);
+ close(fd);
+}
+
+void cmd_write2(MARK frommark, MARK tomark, int fd)
+{
+ REG long l;
+ REG char *scan;
+ REG int i;
+
for (l = markline(frommark); l <= markline(tomark); l++)
{
/* get the next line */
@@ -231,7 +240,6 @@ void cmd_write(frommark, tomark, cmd, bang, extra)
/* print the line */
twrite(fd, scan, i);
}
- close(fd);
}
diff --git a/system.c b/system.c
index 0279c55..aa92818 100644
--- a/system.c
+++ b/system.c
@@ -22,6 +22,8 @@
#include "config.h"
#include "vi.h"
+#include <unistd.h>
+#include <sys/types.h>
#include <signal.h>
extern char **environ;
@@ -331,7 +333,7 @@ int filter(from, to, cmd)
{
int scratch; /* fd of the scratch file */
int fd; /* fd of the pipe from the filter */
- char scrout[50]; /* name of the scratch out file */
+ char *scrout = NULL; /* name of the scratch out file */
MARK new; /* place where new text should go */
int i;
@@ -339,6 +341,9 @@ int filter(from, to, cmd)
if (to)
{
/* we have lines */
+ scrout = malloc(strlen(o_directory) + 9 + 1); /* strlen("/soXXXXXX") */
+ if (!scrout)
+ return -1;
#if MSDOS || TOS
strcpy(scrout, o_directory);
if ((i=strlen(scrout)) && strchr("\\/:", scrout[i-1]))
@@ -347,6 +352,7 @@ int filter(from, to, cmd)
#else
sprintf(scrout, SCRATCHOUT, o_directory);
#endif
+#if !USE_MKSTEMP
mktemp(scrout);
cmd_write(from, to, CMD_BANG, 0, scrout);
@@ -357,6 +363,13 @@ int filter(from, to, cmd)
unlink(scrout);
return -1;
}
+#else
+ if ((scratch = mkstemp(scrout)) < 0)
+ return -1;
+ /* use those lines as stdin */
+ cmd_write2(from, to, scratch);
+ lseek(scratch, 0L, SEEK_SET);
+#endif
}
else
{
@@ -371,6 +384,7 @@ int filter(from, to, cmd)
{
close(scratch);
unlink(scrout);
+ free(scrout);
}
return -1;
}
@@ -429,6 +443,7 @@ int filter(from, to, cmd)
{
close(scratch);
unlink(scrout);
+ free(scrout);
}
return 0;
}
diff --git a/tmp.c b/tmp.c
index 630f735..2689c87 100644
--- a/tmp.c
+++ b/tmp.c
@@ -23,6 +23,7 @@
# include <sys/stat.h>
# endif
#endif
+#include <malloc.h>
#ifndef NO_MODELINE
@@ -193,7 +194,12 @@ int tmpstart(filename)
tmpname[i++]=SLASH;
sprintf(tmpname+i, TMPNAME+3, sum, statb.st_ino, statb.st_dev);
#else
+# if USE_SNPRINTF
+ snprintf(tmpname, sizeof(tmpname), TMPNAME,
+ o_directory, sum, statb.st_ino, statb.st_dev);
+# else
sprintf(tmpname, TMPNAME, o_directory, sum, statb.st_ino, statb.st_dev);
+# endif
#endif
/* make sure nobody else is editing the same file */
@@ -209,11 +215,28 @@ int tmpstart(filename)
/* create the temp file */
#if ANY_UNIX
- close(creat(tmpname, 0600)); /* only we can read it */
+# if USE_MKSTEMP
+ scan = malloc(strlen(o_directory) + 10 + 1); /* "/elvXXXXXX" */
+ if (scan == NULL) {
+ FAIL("No memory: %s", strerror(errno));
+ }
+ sprintf(scan, "%s/elvXXXXXX", o_directory);
+ if ((tmpfd = mkstemp(scan)) >= 0) {
+ if (link(scan, tmpname) < 0) {
+ close(tmpfd);
+ tmpfd = -1;
+ }
+ unlink(scan);
+ }
+ free(scan);
+# else
+ tmpfd = open(tmpname, O_CREAT|O_WRONLY|O_TRUNC|O_EXCL, 0600);
+ /* only we can read it */
+# endif
#else
close(creat(tmpname, FILEPERMS)); /* anybody body can read it, alas */
-#endif
tmpfd = open(tmpname, O_RDWR | O_BINARY);
+#endif
if (tmpfd < 0)
{
FAIL("Can't create temporary file, errno=%d", errno);