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