tarfn.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. /*
  2. * libdpkg - Debian packaging suite library routines
  3. * tarfn.c - tar archive extraction functions
  4. *
  5. * Copyright © 1995 Bruce Perens
  6. * Copyright © 2007-2011,2013-2014 Guillem Jover <guillem@debian.org>
  7. *
  8. * This is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. */
  21. #include <config.h>
  22. #include <compat.h>
  23. #include <sys/stat.h>
  24. #include <errno.h>
  25. #include <string.h>
  26. #include <pwd.h>
  27. #include <grp.h>
  28. #include <unistd.h>
  29. #include <inttypes.h>
  30. #include <stdlib.h>
  31. #include <stdio.h>
  32. #include <dpkg/macros.h>
  33. #include <dpkg/dpkg.h>
  34. #include <dpkg/tarfn.h>
  35. #define TAR_MAGIC_USTAR "ustar\0" "00"
  36. #define TAR_MAGIC_GNU "ustar " " \0"
  37. struct tar_header {
  38. char name[100];
  39. char mode[8];
  40. char uid[8];
  41. char gid[8];
  42. char size[12];
  43. char mtime[12];
  44. char checksum[8];
  45. char linkflag;
  46. char linkname[100];
  47. char magic[8];
  48. char user[32];
  49. char group[32];
  50. char devmajor[8];
  51. char devminor[8];
  52. /* Only valid on ustar. */
  53. char prefix[155];
  54. };
  55. /**
  56. * Convert an ASCII octal string to an intmax_t.
  57. */
  58. static intmax_t
  59. OtoM(const char *s, int size)
  60. {
  61. intmax_t n = 0;
  62. while (*s == ' ') {
  63. s++;
  64. size--;
  65. }
  66. while (--size >= 0 && *s >= '0' && *s <= '7')
  67. n = (n * 010) + (*s++ - '0');
  68. return n;
  69. }
  70. static char *
  71. get_prefix_name(struct tar_header *h)
  72. {
  73. char *path;
  74. m_asprintf(&path, "%.*s/%.*s", (int)sizeof(h->prefix), h->prefix,
  75. (int)sizeof(h->name), h->name);
  76. return path;
  77. }
  78. static mode_t
  79. get_unix_mode(struct tar_header *h)
  80. {
  81. mode_t mode;
  82. enum tar_filetype type;
  83. type = (enum tar_filetype)h->linkflag;
  84. switch (type) {
  85. case TAR_FILETYPE_FILE0:
  86. case TAR_FILETYPE_FILE:
  87. mode = S_IFREG;
  88. break;
  89. case TAR_FILETYPE_SYMLINK:
  90. mode = S_IFLNK;
  91. break;
  92. case TAR_FILETYPE_DIR:
  93. mode = S_IFDIR;
  94. break;
  95. case TAR_FILETYPE_CHARDEV:
  96. mode = S_IFCHR;
  97. break;
  98. case TAR_FILETYPE_BLOCKDEV:
  99. mode = S_IFBLK;
  100. break;
  101. case TAR_FILETYPE_FIFO:
  102. mode = S_IFIFO;
  103. break;
  104. case TAR_FILETYPE_HARDLINK:
  105. default:
  106. mode = 0;
  107. break;
  108. }
  109. mode |= OtoM(h->mode, sizeof(h->mode));
  110. return mode;
  111. }
  112. static long
  113. tar_header_checksum(struct tar_header *h)
  114. {
  115. unsigned char *s = (unsigned char *)h;
  116. unsigned int i;
  117. const size_t checksum_offset = offsetof(struct tar_header, checksum);
  118. long sum;
  119. /* Treat checksum field as all blank. */
  120. sum = ' ' * sizeof(h->checksum);
  121. for (i = checksum_offset; i > 0; i--)
  122. sum += *s++;
  123. /* Skip the real checksum field. */
  124. s += sizeof(h->checksum);
  125. for (i = TARBLKSZ - checksum_offset - sizeof(h->checksum); i > 0; i--)
  126. sum += *s++;
  127. return sum;
  128. }
  129. static int
  130. tar_header_decode(struct tar_header *h, struct tar_entry *d)
  131. {
  132. struct passwd *passwd = NULL;
  133. struct group *group = NULL;
  134. long checksum;
  135. if (memcmp(h->magic, TAR_MAGIC_GNU, 6) == 0)
  136. d->format = TAR_FORMAT_GNU;
  137. else if (memcmp(h->magic, TAR_MAGIC_USTAR, 6) == 0)
  138. d->format = TAR_FORMAT_USTAR;
  139. else
  140. d->format = TAR_FORMAT_OLD;
  141. d->type = (enum tar_filetype)h->linkflag;
  142. if (d->type == TAR_FILETYPE_FILE0)
  143. d->type = TAR_FILETYPE_FILE;
  144. /* Concatenate prefix and name to support ustar style long names. */
  145. if (d->format == TAR_FORMAT_USTAR && h->prefix[0] != '\0')
  146. d->name = get_prefix_name(h);
  147. else
  148. d->name = m_strndup(h->name, sizeof(h->name));
  149. d->linkname = m_strndup(h->linkname, sizeof(h->linkname));
  150. d->stat.mode = get_unix_mode(h);
  151. d->size = (off_t)OtoM(h->size, sizeof(h->size));
  152. d->mtime = (time_t)OtoM(h->mtime, sizeof(h->mtime));
  153. d->dev = makedev(OtoM(h->devmajor, sizeof(h->devmajor)),
  154. OtoM(h->devminor, sizeof(h->devminor)));
  155. if (*h->user)
  156. passwd = getpwnam(h->user);
  157. if (passwd)
  158. d->stat.uid = passwd->pw_uid;
  159. else
  160. d->stat.uid = (uid_t)OtoM(h->uid, sizeof(h->uid));
  161. if (*h->group)
  162. group = getgrnam(h->group);
  163. if (group)
  164. d->stat.gid = group->gr_gid;
  165. else
  166. d->stat.gid = (gid_t)OtoM(h->gid, sizeof(h->gid));
  167. checksum = OtoM(h->checksum, sizeof(h->checksum));
  168. return tar_header_checksum(h) == checksum;
  169. }
  170. /**
  171. * Decode a GNU longlink or longname from the tar archive.
  172. *
  173. * The way the GNU long{link,name} stuff works is like this:
  174. *
  175. * - The first header is a “dummy” header that contains the size of the
  176. * filename.
  177. * - The next N headers contain the filename.
  178. * - After the headers with the filename comes the “real” header with a
  179. * bogus name or link.
  180. */
  181. static int
  182. tar_gnu_long(void *ctx, const struct tar_operations *ops, struct tar_entry *te,
  183. char **longp)
  184. {
  185. char buf[TARBLKSZ];
  186. char *bp;
  187. int status = 0;
  188. int long_read;
  189. free(*longp);
  190. *longp = bp = m_malloc(te->size);
  191. for (long_read = te->size; long_read > 0; long_read -= TARBLKSZ) {
  192. int copysize;
  193. status = ops->read(ctx, buf, TARBLKSZ);
  194. if (status == TARBLKSZ)
  195. status = 0;
  196. else {
  197. /* Read partial header record? */
  198. if (status > 0) {
  199. errno = 0;
  200. status = -1;
  201. }
  202. /* If we didn't get TARBLKSZ bytes read, punt. */
  203. break;
  204. }
  205. copysize = min(long_read, TARBLKSZ);
  206. memcpy(bp, buf, copysize);
  207. bp += copysize;
  208. };
  209. return status;
  210. }
  211. static void
  212. tar_entry_destroy(struct tar_entry *te)
  213. {
  214. free(te->name);
  215. free(te->linkname);
  216. }
  217. struct symlinkList {
  218. struct symlinkList *next;
  219. struct tar_entry h;
  220. };
  221. int
  222. tar_extractor(void *ctx, const struct tar_operations *ops)
  223. {
  224. int status;
  225. char buffer[TARBLKSZ];
  226. struct tar_entry h;
  227. char *next_long_name, *next_long_link;
  228. struct symlinkList *symlink_head, *symlink_tail, *symlink_node;
  229. next_long_name = NULL;
  230. next_long_link = NULL;
  231. symlink_tail = symlink_head = NULL;
  232. h.name = NULL;
  233. h.linkname = NULL;
  234. while ((status = ops->read(ctx, buffer, TARBLKSZ)) == TARBLKSZ) {
  235. int name_len;
  236. if (!tar_header_decode((struct tar_header *)buffer, &h)) {
  237. if (h.name[0] == '\0') {
  238. /* End of tape. */
  239. status = 0;
  240. } else {
  241. /* Indicates broken tarfile:
  242. * “Header checksum error”. */
  243. errno = 0;
  244. status = -1;
  245. }
  246. tar_entry_destroy(&h);
  247. break;
  248. }
  249. if (h.type != TAR_FILETYPE_GNU_LONGLINK &&
  250. h.type != TAR_FILETYPE_GNU_LONGNAME) {
  251. if (next_long_name)
  252. h.name = next_long_name;
  253. if (next_long_link)
  254. h.linkname = next_long_link;
  255. next_long_link = NULL;
  256. next_long_name = NULL;
  257. }
  258. if (h.name[0] == '\0') {
  259. /* Indicates broken tarfile: “Bad header data”. */
  260. errno = 0;
  261. status = -1;
  262. tar_entry_destroy(&h);
  263. break;
  264. }
  265. name_len = strlen(h.name);
  266. switch (h.type) {
  267. case TAR_FILETYPE_FILE:
  268. /* Compatibility with pre-ANSI ustar. */
  269. if (h.name[name_len - 1] != '/') {
  270. status = ops->extract_file(ctx, &h);
  271. break;
  272. }
  273. /* Else, fall through. */
  274. case TAR_FILETYPE_DIR:
  275. if (h.name[name_len - 1] == '/') {
  276. h.name[name_len - 1] = '\0';
  277. }
  278. status = ops->mkdir(ctx, &h);
  279. break;
  280. case TAR_FILETYPE_HARDLINK:
  281. status = ops->link(ctx, &h);
  282. break;
  283. case TAR_FILETYPE_SYMLINK:
  284. symlink_node = m_malloc(sizeof(*symlink_node));
  285. memcpy(&symlink_node->h, &h, sizeof(struct tar_entry));
  286. symlink_node->h.name = m_strdup(h.name);
  287. symlink_node->h.linkname = m_strdup(h.linkname);
  288. symlink_node->next = NULL;
  289. if (symlink_head)
  290. symlink_tail->next = symlink_node;
  291. else
  292. symlink_head = symlink_node;
  293. symlink_tail = symlink_node;
  294. status = 0;
  295. break;
  296. case TAR_FILETYPE_CHARDEV:
  297. case TAR_FILETYPE_BLOCKDEV:
  298. case TAR_FILETYPE_FIFO:
  299. status = ops->mknod(ctx, &h);
  300. break;
  301. case TAR_FILETYPE_GNU_LONGLINK:
  302. status = tar_gnu_long(ctx, ops, &h, &next_long_link);
  303. break;
  304. case TAR_FILETYPE_GNU_LONGNAME:
  305. status = tar_gnu_long(ctx, ops, &h, &next_long_name);
  306. break;
  307. default:
  308. /* Indicates broken tarfile: “Bad header field”. */
  309. errno = 0;
  310. status = -1;
  311. }
  312. tar_entry_destroy(&h);
  313. if (status != 0)
  314. /* Pass on status from coroutine. */
  315. break;
  316. }
  317. while (symlink_head) {
  318. symlink_node = symlink_head->next;
  319. if (status == 0)
  320. status = ops->symlink(ctx, &symlink_head->h);
  321. tar_entry_destroy(&symlink_head->h);
  322. free(symlink_head);
  323. symlink_head = symlink_node;
  324. }
  325. /* Make sure we free the long names, in case of a bogus or truncated
  326. * tar archive with long entries not followed by a normal entry. */
  327. free(next_long_name);
  328. free(next_long_link);
  329. if (status > 0) {
  330. /* Indicates broken tarfile: “Read partial header record”. */
  331. errno = 0;
  332. return -1;
  333. } else {
  334. /* Return whatever I/O function returned. */
  335. return status;
  336. }
  337. }