File: patch-tempfile.diff

package info (click to toggle)
elvis-tiny 1.4-25
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 2,104 kB
  • sloc: ansic: 13,810; sh: 25; makefile: 13
file content (209 lines) | stat: -rw-r--r-- 5,309 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
From: Topi Miettinen <Topi.Miettinen@nic.fi>
To: submit@bugs.debian.org
Date: Tue, 17 Oct 2000 20:30:00 +0300
Subject: 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.


--- elvis-tiny-1.4/Makefile.mix.orig	2012-06-29 20:26:25.262635031 +0000
+++ elvis-tiny-1.4/Makefile.mix	2012-06-29 20:23:07.000000000 +0000
@@ -45,7 +45,8 @@
 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 -ruN elvis-tiny-1.4.b4/cmd1.c elvis-tiny-1.4/cmd1.c
--- elvis-tiny-1.4.b4/cmd1.c	Tue Nov 28 11:50:09 2000
+++ elvis-tiny-1.4/cmd1.c	Tue Nov 28 11:53:23 2000
@@ -158,6 +158,8 @@
 	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 @@
 {
 	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 @@
 			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 @@
 		/* print the line */
 		twrite(fd, scan, i);
 	}
-	close(fd);
 }	
 
 
diff -ruN elvis-tiny-1.4.b4/system.c elvis-tiny-1.4/system.c
--- elvis-tiny-1.4.b4/system.c	Tue Nov 28 11:50:09 2000
+++ elvis-tiny-1.4/system.c	Tue Nov 28 12:00:54 2000
@@ -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	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 @@
 	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 @@
 #else
 		sprintf(scrout, SCRATCHOUT, o_directory);
 #endif
+#if !USE_MKSTEMP
 		mktemp(scrout);
 		cmd_write(from, to, CMD_BANG, 0, scrout);
 
@@ -357,6 +363,13 @@
 			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 @@
 		{
 			close(scratch);
 			unlink(scrout);
+			free(scrout);
 		}
 		return -1;
 	}
@@ -429,6 +443,7 @@
 	{
 		close(scratch);
 		unlink(scrout);
+		free(scrout);
 	}
 	return 0;
 }
diff -ruN elvis-tiny-1.4.b4/tmp.c elvis-tiny-1.4/tmp.c
--- elvis-tiny-1.4.b4/tmp.c	Tue Nov 28 11:50:09 2000
+++ elvis-tiny-1.4/tmp.c	Tue Nov 28 13:02:18 2000
@@ -23,6 +23,7 @@
 #  include <sys/stat.h>
 # endif
 #endif
+#include <malloc.h>
 
 
 #ifndef NO_MODELINE
@@ -193,7 +194,12 @@
 		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 @@
 
 	/* 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);