summaryrefslogtreecommitdiff
blob: 1ee4aee55e5edbbe453f48304d99d2a6137f5738 (plain)
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
Ripped from Fedora.

Get rid of a possible race condition:
 - close output file
  - bad man plays with output file
 - try to chmod output file
Run the chmod on the file descriptor before we close it instead.

--- gzip-1.3.5/gzip.c
+++ gzip-1.3.5/gzip.c
@@ -881,6 +881,20 @@
     }
 
     close(ifd);
+    /* ofd ownership and permissions have to be set before close(ofd)*/
+    if (!to_stdout) {
+        if (fchmod(ofd, istat.st_mode & 07777)) {
+            int e = errno;
+	    WARN((stderr, "%s: ", progname));
+            if (!quiet) {
+	        errno = e;
+	        perror(ofname);
+	    }
+        } 						             
+#ifndef NO_CHOWN
+        fchown(ofd, istat.st_uid, istat.st_gid);  /* Copy ownership */
+#endif
+    }
     if (!to_stdout && close(ofd)) {
 	write_error();
     }
@@ -902,7 +916,7 @@
 	}
 	fprintf(stderr, "\n");
     }
-    /* Copy modes, times, ownership, and remove the input file */
+    /* Copy times and remove the input file */
     if (!to_stdout) {
 	copy_stat(&istat);
     }
@@ -1715,7 +1729,7 @@
 
 
 /* ========================================================================
- * Copy modes, times, ownership from input file to output file.
+ * Copy times from input file to output file.
  * IN assertion: to_stdout is false.
  */
 local void copy_stat(ifstat)
@@ -1730,18 +1744,6 @@
     }
     reset_times(ofname, ifstat);
 #endif
-    /* Copy the protection modes */
-    if (chmod(ofname, ifstat->st_mode & 07777)) {
-	int e = errno;
-	WARN((stderr, "%s: ", progname));
-	if (!quiet) {
-	    errno = e;
-	    perror(ofname);
-	}
-    }
-#ifndef NO_CHOWN
-    chown(ofname, ifstat->st_uid, ifstat->st_gid);  /* Copy ownership */
-#endif
     remove_ofname = 0;
     /* It's now safe to remove the input file: */
     if (xunlink (ifname)) {