|
1 From b3b5611e046b93fb20aa783d6d11d986f33f91f6 Mon Sep 17 00:00:00 2001 |
|
2 From: Paul Eggert <eggert <at> cs.ucla.edu> |
|
3 Date: Thu, 3 Oct 2013 21:12:09 -0700 |
|
4 Subject: [PATCH] znew: avoid denial-of-service issue |
|
5 |
|
6 Reported by Rich Burridge in <http://bugs.gnu.org/15522>. |
|
7 * znew.in: Rewrite to avoid the need for a temporary file in /tmp. |
|
8 That way, we avoid the need for set -C |
|
9 and worrying about denial of service. |
|
10 Use touch -r and chmod --reference rather than cpmod. |
|
11 Assume cp -p works, as it's now universal. |
|
12 Quote 'echo' args better, while we're at it. |
|
13 (warn, tmp, cpmod, cpmodarg): Remove. |
|
14 (GZIP): Unset, so that we needn't test for gzip extension. |
|
15 (ext): Now always '.gz'. |
|
16 * znew.1: Document the change of implementation assumptions. |
|
17 --- |
|
18 diff --git a/znew.1 b/znew.1 |
|
19 index dcdf84f..2a7e5e1 100644 |
|
20 --- a/znew.1 |
|
21 +++ b/znew.1 |
|
22 @@ -32,9 +32,16 @@ Keep a .Z file when it is smaller than the .gz file; implies |
|
23 .SH "SEE ALSO" |
|
24 gzip(1), zmore(1), zdiff(1), zgrep(1), zforce(1), gzexe(1), compress(1) |
|
25 .SH BUGS |
|
26 -.I Znew |
|
27 -does not maintain the time stamp with the -P option if |
|
28 -.I cpmod(1) |
|
29 -is not available and |
|
30 -.I touch(1) |
|
31 -does not support the -r option. |
|
32 +If the |
|
33 +.B \-P |
|
34 +option is used, |
|
35 +.I znew |
|
36 +does not maintain the time stamp if |
|
37 +.IR touch (1) |
|
38 +does not support the |
|
39 +.B \-r |
|
40 +option, and does not maintain permissions if |
|
41 +.IR chmod (1) |
|
42 +does not support the |
|
43 +.B \-\-reference |
|
44 +option. |
|
45 diff --git a/znew.in b/znew.in |
|
46 index 9bd3ce9..d16311a 100644 |
|
47 --- a/znew.in |
|
48 +++ b/znew.in |
|
49 @@ -58,33 +58,9 @@ new=0 |
|
50 block=1024 |
|
51 # block is the disk block size (best guess, need not be exact) |
|
52 |
|
53 -warn="(does not preserve modes and timestamp)" |
|
54 -tmp=${TMPDIR-/tmp}/zfoo.$$ |
|
55 -set -C |
|
56 -echo hi > $tmp || exit |
|
57 -if test -z "`(${CPMOD-cpmod} $tmp $tmp) 2>&1`"; then |
|
58 - cpmod=${CPMOD-cpmod} |
|
59 - warn="" |
|
60 -fi |
|
61 - |
|
62 -if test -z "$cpmod" && ${TOUCH-touch} -r $tmp $tmp 2>/dev/null; then |
|
63 - cpmod="${TOUCH-touch}" |
|
64 - cpmodarg="-r" |
|
65 - warn="(does not preserve file modes)" |
|
66 -fi |
|
67 - |
|
68 -# check if GZIP env. variable uses -S or --suffix |
|
69 -gzip -q $tmp |
|
70 -ext=`echo $tmp* | sed "s|$tmp||"` |
|
71 -rm -f $tmp* |
|
72 -if test -z "$ext"; then |
|
73 - echo znew: error determining gzip extension |
|
74 - exit 1 |
|
75 -fi |
|
76 -if test "$ext" = ".Z"; then |
|
77 - echo znew: cannot use .Z as gzip extension. |
|
78 - exit 1 |
|
79 -fi |
|
80 +# Beware -s or --suffix in $GZIP. |
|
81 +unset GZIP |
|
82 +ext=.gz |
|
83 |
|
84 for arg |
|
85 do |
|
86 @@ -116,26 +92,27 @@ if test -n "$opt"; then |
|
87 fi |
|
88 |
|
89 for i do |
|
90 - n=`echo $i | sed 's/.Z$//'` |
|
91 + n=`echo "$i" | sed 's/.Z$//'` |
|
92 if test ! -f "$n.Z" ; then |
|
93 - echo $n.Z not found |
|
94 + echo "$n.Z not found" |
|
95 res=1; continue |
|
96 fi |
|
97 test $keep -eq 1 && old=`wc -c < "$n.Z"` |
|
98 if test $pipe -eq 1; then |
|
99 if gzip -d < "$n.Z" | gzip $opt > "$n$ext"; then |
|
100 # Copy file attributes from old file to new one, if possible. |
|
101 - test -n "$cpmod" && $cpmod $cpmodarg "$n.Z" "$n$ext" 2> /dev/null |
|
102 + touch -r"$n.Z" -- "$n$ext" 2>/dev/null |
|
103 + chmod --reference="$n.Z" -- "$n$ext" 2>/dev/null |
|
104 else |
|
105 - echo error while recompressing $n.Z |
|
106 + echo "error while recompressing $n.Z" |
|
107 res=1; continue |
|
108 fi |
|
109 else |
|
110 if test $check -eq 1; then |
|
111 - if cp -p "$n.Z" "$n.$$" 2> /dev/null || cp "$n.Z" "$n.$$"; then |
|
112 + if cp -p "$n.Z" "$n.$$"; then |
|
113 : |
|
114 else |
|
115 - echo cannot backup "$n.Z" |
|
116 + echo "cannot backup $n.Z" |
|
117 res=1; continue |
|
118 fi |
|
119 fi |
|
120 @@ -143,7 +120,7 @@ for i do |
|
121 : |
|
122 else |
|
123 test $check -eq 1 && mv "$n.$$" "$n.Z" |
|
124 - echo error while uncompressing $n.Z |
|
125 + echo "error while uncompressing $n.Z" |
|
126 res=1; continue |
|
127 fi |
|
128 if gzip $opt "$n"; then |
|
129 @@ -151,10 +128,10 @@ for i do |
|
130 else |
|
131 if test $check -eq 1; then |
|
132 mv "$n.$$" "$n.Z" && rm -f "$n" |
|
133 - echo error while recompressing $n |
|
134 + echo "error while recompressing $n" |
|
135 else |
|
136 # compress $n (might be dangerous if disk full) |
|
137 - echo error while recompressing $n, left uncompressed |
|
138 + echo "error while recompressing $n, left uncompressed" |
|
139 fi |
|
140 res=1; continue |
|
141 fi |
|
142 @@ -175,7 +152,7 @@ for i do |
|
143 else |
|
144 test $pipe -eq 0 && mv "$n.$$" "$n.Z" |
|
145 rm -f "$n$ext" |
|
146 - echo error while testing $n$ext, $n.Z unchanged |
|
147 + echo "error while testing $n$ext, $n.Z unchanged" |
|
148 res=1; continue |
|
149 fi |
|
150 elif test $pipe -eq 1; then |
|
151 -- |
|
152 1.8.3.1 |