0010-pax-Fix-GNU-long-name-handling-with-short-read.patch (4518B)
1 From ec3fd37495e977af375a98a472d19ae0ccbcd874 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 e5b0a4ee5d1..f0a55abe2f7 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 @@ -208,15 +202,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 @@ -1243,3 +1230,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 68534dcbe25..e84f9e0d3d6 100644 118 --- a/bin/pax/buf_subs.c 119 +++ b/bin/pax/buf_subs.c 120 @@ -673,9 +673,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 89b4872988b..8aa3d249923 100644 133 --- a/bin/pax/file_subs.c 134 +++ b/bin/pax/file_subs.c 135 @@ -919,7 +919,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 @@ -978,29 +977,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.26.2 176