tar.tests 10 KB

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