logo

oasis

Own branch of Oasis Linux (upstream: <https://git.sr.ht/~mcf/oasis/>) git clone https://anongit.hacktivis.me/git/oasis.git

0009-pax-Fix-GNU-long-name-handling-with-short-read.patch (4518B)


  1. From f88fb1145beac6cce7012b506579d23e0b9826a2 Mon Sep 17 00:00:00 2001
  2. From: Michael Forney <mforney@mforney.org>
  3. Date: Sat, 3 Dec 2016 20:49:24 -0800
  4. Subject: [PATCH] pax: Fix GNU long name handling with short read
  5. ---
  6. bin/pax/ar_subs.c | 66 +++++++++++++++++++++++++++++++++------------
  7. bin/pax/buf_subs.c | 4 +--
  8. bin/pax/file_subs.c | 25 +----------------
  9. 3 files changed, 51 insertions(+), 44 deletions(-)
  10. diff --git a/bin/pax/ar_subs.c b/bin/pax/ar_subs.c
  11. index f018108af59..4c49efa1362 100644
  12. --- a/bin/pax/ar_subs.c
  13. +++ b/bin/pax/ar_subs.c
  14. @@ -37,6 +37,7 @@
  15. #include <sys/types.h>
  16. #include <sys/stat.h>
  17. #include <sys/time.h>
  18. +#include <err.h>
  19. #include <errno.h>
  20. #include <fcntl.h>
  21. #include <signal.h>
  22. @@ -51,6 +52,7 @@
  23. static void wr_archive(ARCHD *, int is_app);
  24. static int get_arc(void);
  25. static int next_head(ARCHD *);
  26. +static int rd_gnu_string(ARCHD *);
  27. extern sigset_t s_mask;
  28. /*
  29. @@ -93,16 +95,8 @@ list(void)
  30. * step through the archive until the format says it is done
  31. */
  32. while (next_head(arcn) == 0) {
  33. - if (arcn->type == PAX_GLL || arcn->type == PAX_GLF) {
  34. - /*
  35. - * we need to read, to get the real filename
  36. - */
  37. - off_t cnt;
  38. - if (!rd_wrfile(arcn, arcn->type == PAX_GLF
  39. - ? -1 : -2, &cnt))
  40. - (void)rd_skip(cnt + arcn->pad);
  41. + if (rd_gnu_string(arcn))
  42. continue;
  43. - }
  44. /*
  45. * check for pattern, and user specified options match.
  46. @@ -245,15 +239,8 @@ extract(void)
  47. * says it is done
  48. */
  49. while (next_head(arcn) == 0) {
  50. - if (arcn->type == PAX_GLL || arcn->type == PAX_GLF) {
  51. - /*
  52. - * we need to read, to get the real filename
  53. - */
  54. - if (!rd_wrfile(arcn, arcn->type == PAX_GLF
  55. - ? -1 : -2, &cnt))
  56. - (void)rd_skip(cnt + arcn->pad);
  57. + if (rd_gnu_string(arcn))
  58. continue;
  59. - }
  60. /*
  61. * check for pattern, and user specified options match. When
  62. @@ -1282,3 +1269,48 @@ get_arc(void)
  63. paxwarn(1, "Sorry, unable to determine archive format.");
  64. return(-1);
  65. }
  66. +
  67. +/*
  68. + * rd_gnu_string()
  69. + * Read the file contents into an allocated string if it is a GNU tar
  70. + * long link/file.
  71. + * Return:
  72. + * 1 if gnu string read, 0 otherwise
  73. + */
  74. +
  75. +static int
  76. +rd_gnu_string(ARCHD *arcn)
  77. +{
  78. + char **strp;
  79. +
  80. + switch (arcn->type) {
  81. + case PAX_GLF:
  82. + strp = &gnu_name_string;
  83. + break;
  84. + case PAX_GLL:
  85. + strp = &gnu_link_string;
  86. + break;
  87. + default:
  88. + strp = NULL;
  89. + break;
  90. + }
  91. + if (!strp)
  92. + return 0;
  93. + /*
  94. + * we need to read, to get the real filename
  95. + */
  96. + if (*strp)
  97. + err(1, "WARNING! Major Internal Error! GNU hack Failing!");
  98. + *strp = malloc(arcn->sb.st_size + 1);
  99. + if (*strp == NULL) {
  100. + paxwarn(1, "Out of memory");
  101. + (void)rd_skip(arcn->skip + arcn->pad);
  102. + } else if (rd_wrbuf(*strp, arcn->sb.st_size) < arcn->sb.st_size) {
  103. + free(*strp);
  104. + *strp = NULL;
  105. + } else {
  106. + (*strp)[arcn->sb.st_size] = '\0';
  107. + (void)rd_skip(arcn->pad);
  108. + }
  109. + return 1;
  110. +}
  111. diff --git a/bin/pax/buf_subs.c b/bin/pax/buf_subs.c
  112. index 25dfed5b69b..e3e22a09cc6 100644
  113. --- a/bin/pax/buf_subs.c
  114. +++ b/bin/pax/buf_subs.c
  115. @@ -676,9 +676,7 @@ rd_wrfile(ARCHD *arcn, int ofd, off_t *left)
  116. * pass the blocksize of the file being written to the write routine,
  117. * if the size is zero, use the default MINFBSZ
  118. */
  119. - if (ofd < 0)
  120. - sz = PAXPATHLEN + 1; /* GNU tar long link/file */
  121. - else if (fstat(ofd, &sb) == 0) {
  122. + if (fstat(ofd, &sb) == 0) {
  123. if (sb.st_blksize > 0)
  124. sz = (int)sb.st_blksize;
  125. } else
  126. diff --git a/bin/pax/file_subs.c b/bin/pax/file_subs.c
  127. index 9f482480a3b..ae0caf29f6c 100644
  128. --- a/bin/pax/file_subs.c
  129. +++ b/bin/pax/file_subs.c
  130. @@ -924,7 +924,6 @@ file_write(int fd, char *str, int cnt, int *rem, int *isempt, int sz,
  131. char *end;
  132. int wcnt;
  133. char *st = str;
  134. - char **strp;
  135. /*
  136. * while we have data to process
  137. @@ -983,29 +982,7 @@ file_write(int fd, char *str, int cnt, int *rem, int *isempt, int sz,
  138. /*
  139. * have non-zero data in this file system block, have to write
  140. */
  141. - switch (fd) {
  142. - case -1:
  143. - strp = &gnu_name_string;
  144. - break;
  145. - case -2:
  146. - strp = &gnu_link_string;
  147. - break;
  148. - default:
  149. - strp = NULL;
  150. - break;
  151. - }
  152. - if (strp) {
  153. - if (*strp)
  154. - err(1, "WARNING! Major Internal Error! GNU hack Failing!");
  155. - *strp = malloc(wcnt + 1);
  156. - if (*strp == NULL) {
  157. - paxwarn(1, "Out of memory");
  158. - return(-1);
  159. - }
  160. - memcpy(*strp, st, wcnt);
  161. - (*strp)[wcnt] = '\0';
  162. - break;
  163. - } else if (write(fd, st, wcnt) != wcnt) {
  164. + if (write(fd, st, wcnt) != wcnt) {
  165. syswarn(1, errno, "Failed write to file %s", name);
  166. return(-1);
  167. }
  168. --
  169. 2.49.0