diff options
author | Topi Miettinen <Topi.Miettinen@nic.fi> | 2000-10-17 20:30:00 +0300 |
---|---|---|
committer | Miquel van Smoorenburg <miquels@debian.org> | 2016-11-11 07:07:17 -0800 |
commit | 9f2e9d20f0bbf50a57071ed4e7ed8c364d654cfd (patch) | |
tree | 1cf400866d8b27f56c512b383050f93efc6eb2e0 | |
parent | 498615b922d85f05775e13646dddd0697bc77c31 (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.mix | 3 | ||||
-rw-r--r-- | cmd1.c | 16 | ||||
-rw-r--r-- | system.c | 17 | ||||
-rw-r--r-- | tmp.c | 27 |
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`\"\' @@ -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); } @@ -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; } @@ -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); |