busybox/testsuite/tar.tests
<<
>>
Prefs
   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