blob: 9f7ce15878d442c16587f3384bf9fba9072f62ad
1 | #!/bin/sh |
2 | # Copyright 2009 by Denys Vlasenko |
3 | # Licensed under GPLv2, see file LICENSE in this source tree. |
4 | |
5 | . ./testing.sh |
6 | |
7 | unset LANG |
8 | unset LANGUAGE |
9 | unset LC_COLLATE |
10 | unset LC_ALL |
11 | umask 022 |
12 | |
13 | rm -rf tar.tempdir 2>/dev/null |
14 | mkdir tar.tempdir && cd tar.tempdir || exit 1 |
15 | |
16 | # testing "test name" "script" "expected result" "file input" "stdin" |
17 | |
18 | testing "Empty file is not a tarball" '\ |
19 | tar xvf - 2>&1; echo $? |
20 | ' "\ |
21 | tar: short read |
22 | 1 |
23 | " \ |
24 | "" "" |
25 | SKIP= |
26 | |
27 | optional FEATURE_SEAMLESS_GZ GUNZIP |
28 | # In NOMMU case, "invalid magic" message comes from gunzip child process. |
29 | # Otherwise, it comes from tar. |
30 | # Need to fix output up to avoid false positive. |
31 | testing "Empty file is not a tarball.tar.gz" '\ |
32 | { tar xvzf - 2>&1; echo $?; } | grep -Fv "invalid magic" |
33 | ' "\ |
34 | tar: short read |
35 | 1 |
36 | " \ |
37 | "" "" |
38 | SKIP= |
39 | |
40 | testing "Two zeroed blocks is a ('truncated') empty tarball" '\ |
41 | dd if=/dev/zero bs=512 count=2 2>/dev/null | tar xvf - 2>&1; echo $? |
42 | ' "\ |
43 | 0 |
44 | " \ |
45 | "" "" |
46 | SKIP= |
47 | |
48 | testing "Twenty zeroed blocks is an empty tarball" '\ |
49 | dd if=/dev/zero bs=512 count=20 2>/dev/null | tar xvf - 2>&1; echo $? |
50 | ' "\ |
51 | 0 |
52 | " \ |
53 | "" "" |
54 | SKIP= |
55 | |
56 | # "tar cf test.tar input input_dir/ input_hard1 input_hard2 input_hard1 input_dir/ input": |
57 | # GNU tar 1.26 records as hardlinks: |
58 | # input_hard2 -> input_hard1 |
59 | # input_hard1 -> input_hard1 (!!!) |
60 | # input_dir/file -> input_dir/file |
61 | # input -> input |
62 | # As of 1.24.0, we don't record last two: for them, nlink==1 |
63 | # and we check for "hardlink"ness only files with nlink!=1 |
64 | # We also don't use "hrw-r--r--" notation for hardlinks in "tar tv" listing. |
65 | optional FEATURE_TAR_CREATE FEATURE_LS_SORTFILES |
66 | testing "tar hardlinks and repeated files" '\ |
67 | rm -rf input_* test.tar 2>/dev/null |
68 | >input_hard1 |
69 | ln input_hard1 input_hard2 |
70 | mkdir input_dir |
71 | >input_dir/file |
72 | chmod -R 644 * |
73 | chmod 755 input_dir |
74 | tar cf test.tar input input_dir/ input_hard1 input_hard2 input_hard1 input_dir/ input |
75 | tar tvf test.tar | sed "s/.*[0-9] input/input/" |
76 | rm -rf input_dir |
77 | tar xf test.tar 2>&1 |
78 | echo Ok: $? |
79 | ls -l . input_dir/* | grep input_ | sed "s/\\(^[^ ]*\\) .* input/\\1 input/" |
80 | ' "\ |
81 | input |
82 | input_dir/ |
83 | input_dir/file |
84 | input_hard1 |
85 | input_hard2 -> input_hard1 |
86 | input_hard1 -> input_hard1 |
87 | input_dir/ |
88 | input_dir/file |
89 | input |
90 | Ok: 0 |
91 | -rw-r--r-- input_dir/file |
92 | drwxr-xr-x input_dir |
93 | -rw-r--r-- input_hard1 |
94 | -rw-r--r-- input_hard2 |
95 | " \ |
96 | "" "" |
97 | SKIP= |
98 | |
99 | optional FEATURE_TAR_CREATE FEATURE_LS_SORTFILES |
100 | testing "tar hardlinks mode" '\ |
101 | rm -rf input_* test.tar 2>/dev/null |
102 | >input_hard1 |
103 | chmod 741 input_hard1 |
104 | ln input_hard1 input_hard2 |
105 | mkdir input_dir |
106 | ln input_hard1 input_dir |
107 | ln input_hard2 input_dir |
108 | chmod 550 input_dir |
109 | # On some filesystems, input_dir/input_hard2 is returned by readdir |
110 | # BEFORE input_dir/input_hard1! Thats why we cant just "tar cf ... input_*": |
111 | tar cf test.tar input_dir/input_hard* input_hard* |
112 | tar tvf test.tar | sed "s/.*[0-9] input/input/" |
113 | chmod 770 input_dir |
114 | rm -rf input_* |
115 | tar xf test.tar 2>&1 |
116 | echo Ok: $? |
117 | ls -l . input_dir/* | grep "input.*hard" | sed "s/\\(^[^ ]*\\) .* input/\\1 input/" |
118 | ' "\ |
119 | input_dir/input_hard1 |
120 | input_dir/input_hard2 -> input_dir/input_hard1 |
121 | input_hard1 -> input_dir/input_hard1 |
122 | input_hard2 -> input_dir/input_hard1 |
123 | Ok: 0 |
124 | -rwxr----x input_dir/input_hard1 |
125 | -rwxr----x input_dir/input_hard2 |
126 | -rwxr----x input_hard1 |
127 | -rwxr----x input_hard2 |
128 | " \ |
129 | "" "" |
130 | SKIP= |
131 | |
132 | optional FEATURE_TAR_CREATE FEATURE_LS_SORTFILES |
133 | testing "tar symlinks mode" '\ |
134 | rm -rf input_* test.tar 2>/dev/null |
135 | >input_file |
136 | chmod 741 input_file |
137 | ln -s input_file input_soft |
138 | mkdir input_dir |
139 | ln input_file input_dir |
140 | ln input_soft input_dir |
141 | chmod 550 input_dir |
142 | tar cf test.tar input_dir/* input_[fs]* |
143 | tar tvf test.tar | sed "s/.*[0-9] input/input/" | sort |
144 | chmod 770 input_dir |
145 | rm -rf input_* |
146 | tar xf test.tar 2>&1 |
147 | echo Ok: $? |
148 | ls -l . input_dir/* | grep "input_[fs]" | sed "s/\\(^[^ ]*\\) .* input/\\1 input/" |
149 | ' "\ |
150 | input_dir/input_file |
151 | input_dir/input_soft -> input_file |
152 | input_file -> input_dir/input_file |
153 | input_soft -> input_dir/input_soft |
154 | Ok: 0 |
155 | -rwxr----x input_dir/input_file |
156 | lrwxrwxrwx input_file |
157 | -rwxr----x input_file |
158 | lrwxrwxrwx input_file |
159 | " \ |
160 | "" "" |
161 | SKIP= |
162 | |
163 | optional FEATURE_TAR_CREATE FEATURE_TAR_LONG_OPTIONS |
164 | testing "tar --overwrite" "\ |
165 | rm -rf input_* test.tar 2>/dev/null |
166 | ln input input_hard |
167 | tar cf test.tar input_hard |
168 | echo WRONG >input |
169 | # --overwrite opens 'input_hard' without unlinking, |
170 | # thus 'input_hard' still linked to 'input' and we write 'Ok' into it |
171 | tar xf test.tar --overwrite 2>&1 && cat input |
172 | " "\ |
173 | Ok |
174 | " \ |
175 | "Ok\n" "" |
176 | SKIP= |
177 | |
178 | test x"$SKIP_KNOWN_BUGS" = x"" && { |
179 | # Needs to be run under non-root for meaningful test |
180 | optional FEATURE_TAR_CREATE |
181 | testing "tar writing into read-only dir" '\ |
182 | rm -rf input_* test.tar 2>/dev/null |
183 | mkdir input_dir |
184 | >input_dir/input_file |
185 | chmod 550 input_dir |
186 | tar cf test.tar input_dir |
187 | tar tvf test.tar | sed "s/.*[0-9] input/input/" |
188 | chmod 770 input_dir |
189 | rm -rf input_* |
190 | tar xf test.tar 2>&1 |
191 | echo Ok: $? |
192 | ls -l input_dir/* . | grep input_ | sed "s/\\(^[^ ]*\\) .* input/\\1 input/" |
193 | chmod 770 input_dir |
194 | ' "\ |
195 | input_dir/ |
196 | input_dir/input_file |
197 | Ok: 0 |
198 | -rw-r--r-- input_dir/input_file |
199 | dr-xr-x--- input_dir |
200 | " \ |
201 | "" "" |
202 | SKIP= |
203 | } |
204 | |
205 | # Had a bug where on extract autodetect first "switched off" -z |
206 | # and then failed to recognize .tgz extension |
207 | optional FEATURE_TAR_CREATE FEATURE_SEAMLESS_GZ GUNZIP |
208 | testing "tar extract tgz" "\ |
209 | dd count=1 bs=1M if=/dev/zero of=F0 2>/dev/null |
210 | tar -czf F0.tgz F0 |
211 | rm F0 |
212 | tar -xzvf F0.tgz && echo Ok |
213 | rm F0 || echo BAD |
214 | " "\ |
215 | F0 |
216 | Ok |
217 | " \ |
218 | "" "" |
219 | SKIP= |
220 | |
221 | # Do we detect XZ-compressed data (even w/o .tar.xz or txz extension)? |
222 | # (the uuencoded hello_world.txz contains one empty file named "hello_world") |
223 | optional UUDECODE FEATURE_TAR_AUTODETECT FEATURE_SEAMLESS_XZ |
224 | testing "tar extract txz" "\ |
225 | uudecode -o input && tar tf input && echo Ok |
226 | " "\ |
227 | hello_world |
228 | Ok |
229 | " \ |
230 | "" "\ |
231 | begin-base64 644 hello_world.txz |
232 | /Td6WFoAAATm1rRGAgAhARYAAAB0L+Wj4AX/AEldADQZSe6ODIZQ3rSQ8kAJ |
233 | SnMPTX+XWGKW3Yu/Rwqg4Ik5wqgQKgVH97J8yA8IvZ4ahaCQogUNHRkXibr2 |
234 | Q615wcb2G7fJU49AhWAAAAAAUA8gu9DyXfAAAWWADAAAAB5FXGCxxGf7AgAA |
235 | AAAEWVo= |
236 | ==== |
237 | " |
238 | SKIP= |
239 | |
240 | # On extract, everything up to and including last ".." component is stripped |
241 | optional FEATURE_TAR_CREATE |
242 | testing "tar strips /../ on extract" "\ |
243 | rm -rf input_* test.tar 2>/dev/null |
244 | mkdir input_dir |
245 | echo Ok >input_dir/file |
246 | tar cf test.tar ./../tar.tempdir/input_dir/../input_dir 2>&1 |
247 | rm -rf input_* 2>/dev/null |
248 | tar -vxf test.tar 2>&1 |
249 | cat input_dir/file 2>&1 |
250 | " "\ |
251 | tar: removing leading './../tar.tempdir/input_dir/../' from member names |
252 | input_dir/ |
253 | input_dir/file |
254 | Ok |
255 | " \ |
256 | "" "" |
257 | SKIP= |
258 | |
259 | # attack.tar.bz2 has symlink pointing to a system file |
260 | # followed by a regular file with the same name |
261 | # containing "root::0:0::/root:/bin/sh": |
262 | # lrwxrwxrwx root/root passwd -> /tmp/passwd |
263 | # -rw-r--r-- root/root passwd |
264 | # naive tar implementation may end up creating the symlink |
265 | # and then writing into it. |
266 | # The correct implementation unlinks target before |
267 | # creating the second file. |
268 | # We test that /tmp/passwd remains empty: |
269 | optional UUDECODE FEATURE_TAR_AUTODETECT FEATURE_SEAMLESS_BZ2 |
270 | testing "tar does not extract into symlinks" "\ |
271 | >>/tmp/passwd && uudecode -o input && tar xf input 2>&1 && rm passwd; cat /tmp/passwd; echo \$? |
272 | " "\ |
273 | 0 |
274 | " \ |
275 | "" "\ |
276 | begin-base64 644 attack.tar.bz2 |
277 | QlpoOTFBWSZTWRVn/bIAAKt7hMqwAEBAAP2QAhB0Y96AAACACCAAlISgpqe0 |
278 | po0DIaDynqAkpDRP1ANAhiYNSPR8VchKhAz0AK59+DA6FcMKBggOARIJdVHL |
279 | DGllrjs20ATUgR1HmccBX3EhoMnpMJaNyggmxgLDMz54lBnBTJO/1L1lbMS4 |
280 | l4/V8LDoe90yiWJhOJvIypgEfxdyRThQkBVn/bI= |
281 | ==== |
282 | " |
283 | SKIP= |
284 | # And same with -k |
285 | optional UUDECODE FEATURE_TAR_AUTODETECT FEATURE_SEAMLESS_BZ2 |
286 | testing "tar -k does not extract into symlinks" "\ |
287 | >>/tmp/passwd && uudecode -o input && tar xf input -k 2>&1 && rm passwd; cat /tmp/passwd; echo \$? |
288 | " "\ |
289 | tar: can't open 'passwd': File exists |
290 | 0 |
291 | " \ |
292 | "" "\ |
293 | begin-base64 644 attack.tar.bz2 |
294 | QlpoOTFBWSZTWRVn/bIAAKt7hMqwAEBAAP2QAhB0Y96AAACACCAAlISgpqe0 |
295 | po0DIaDynqAkpDRP1ANAhiYNSPR8VchKhAz0AK59+DA6FcMKBggOARIJdVHL |
296 | DGllrjs20ATUgR1HmccBX3EhoMnpMJaNyggmxgLDMz54lBnBTJO/1L1lbMS4 |
297 | l4/V8LDoe90yiWJhOJvIypgEfxdyRThQkBVn/bI= |
298 | ==== |
299 | " |
300 | SKIP= |
301 | |
302 | optional UNICODE_SUPPORT FEATURE_TAR_GNU_EXTENSIONS FEATURE_SEAMLESS_BZ2 FEATURE_TAR_AUTODETECT |
303 | testing "Pax-encoded UTF8 names and symlinks" '\ |
304 | tar xvf ../tar.utf8.tar.bz2 2>&1; echo $? |
305 | export LANG=en_US.UTF-8 |
306 | ls -l etc/ssl/certs/* | sed "s:.*etc/:etc/:" | sort |
307 | unset LANG |
308 | rm -rf etc usr |
309 | ' "\ |
310 | etc/ssl/certs/3b2716e5.0 |
311 | etc/ssl/certs/EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.pem |
312 | etc/ssl/certs/f80cc7f6.0 |
313 | usr/share/ca-certificates/mozilla/EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.crt |
314 | 0 |
315 | etc/ssl/certs/3b2716e5.0 -> EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.pem |
316 | etc/ssl/certs/EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.pem -> /usr/share/ca-certificates/mozilla/EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.crt |
317 | etc/ssl/certs/f80cc7f6.0 -> EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.pem |
318 | " \ |
319 | "" "" |
320 | SKIP= |
321 | |
322 | |
323 | cd .. && rm -rf tar.tempdir || exit 1 |
324 | |
325 | exit $FAILCOUNT |
326 |