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