tar.tests 11 KB

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