1 /* tar.c - read in write tar headers for cpio
2    Copyright (C) 1992-2019 Free Software Foundation, Inc.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3, or (at your option)
7    any later version.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public
15    License along with this program; if not, write to the Free
16    Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17    Boston, MA 02110-1301 USA.  */
18 
19 #include <system.h>
20 
21 #include <stdio.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include "filetypes.h"
25 #include "cpiohdr.h"
26 #include "dstring.h"
27 #include "extern.h"
28 #include <rmt.h>
29 #include "tarhdr.h"
30 
31 /* Stash the tar linkname in static storage.  */
32 
33 static char *
stash_tar_linkname(char * linkname)34 stash_tar_linkname (char *linkname)
35 {
36   static char hold_tar_linkname[TARLINKNAMESIZE + 1];
37 
38   strncpy (hold_tar_linkname, linkname, TARLINKNAMESIZE);
39   hold_tar_linkname[TARLINKNAMESIZE] = '\0';
40   return hold_tar_linkname;
41 }
42 
43 /* Try to split a long file name into prefix and suffix parts separated
44    by a slash. Return the length of the prefix (not counting the slash). */
45 
46 static size_t
split_long_name(const char * name,size_t length)47 split_long_name (const char *name, size_t length)
48 {
49   size_t i;
50 
51   if (length > TARPREFIXSIZE)
52     length = TARPREFIXSIZE+2;
53   for (i = length - 1; i > 0; i--)
54     if (name[i] == '/')
55       break;
56   return i;
57 }
58 
59 /* Stash the tar filename and optional prefix in static storage.  */
60 
61 static char *
stash_tar_filename(char * prefix,char * filename)62 stash_tar_filename (char *prefix, char *filename)
63 {
64   static char hold_tar_filename[TARNAMESIZE + TARPREFIXSIZE + 2];
65   if (prefix == NULL || *prefix == '\0')
66     {
67       strncpy (hold_tar_filename, filename, TARNAMESIZE);
68       hold_tar_filename[TARNAMESIZE] = '\0';
69     }
70   else
71     {
72       strncpy (hold_tar_filename, prefix, TARPREFIXSIZE);
73       hold_tar_filename[TARPREFIXSIZE] = '\0';
74       strcat (hold_tar_filename, "/");
75       strncat (hold_tar_filename, filename, TARNAMESIZE);
76       hold_tar_filename[TARPREFIXSIZE + TARNAMESIZE] = '\0';
77     }
78   return hold_tar_filename;
79 }
80 
81 static int
to_oct_or_error(uintmax_t value,size_t digits,char * where,char const * field,char const * file)82 to_oct_or_error (uintmax_t value, size_t digits, char *where, char const *field,
83 		 char const *file)
84 {
85   if (to_ascii (where, value, digits, LG_8, true))
86     {
87       field_width_error (file, field, value, digits, true);
88       return 1;
89     }
90   return 0;
91 }
92 
93 
94 /* Compute and return a checksum for TAR_HDR,
95    counting the checksum bytes as if they were spaces.  */
96 
97 unsigned int
tar_checksum(struct tar_header * tar_hdr)98 tar_checksum (struct tar_header *tar_hdr)
99 {
100   unsigned int sum = 0;
101   char *p = (char *) tar_hdr;
102   char *q = p + TARRECORDSIZE;
103   int i;
104 
105   while (p < tar_hdr->chksum)
106     sum += *p++ & 0xff;
107   for (i = 0; i < 8; ++i)
108     {
109       sum += ' ';
110       ++p;
111     }
112   while (p < q)
113     sum += *p++ & 0xff;
114   return sum;
115 }
116 
117 #define TO_OCT(file_hdr, c_fld, digits, tar_hdr, tar_field) \
118   do							    \
119     {							    \
120        if (to_oct_or_error (file_hdr -> c_fld,		    \
121 			    digits,			    \
122 			    tar_hdr -> tar_field,	    \
123 			    #tar_field,			    \
124 			    file_hdr->c_name))		    \
125 	 return 1;					    \
126     }							    \
127   while (0)
128 
129 /* Write out header FILE_HDR, including the file name, to file
130    descriptor OUT_DES.  */
131 
132 int
write_out_tar_header(struct cpio_file_stat * file_hdr,int out_des)133 write_out_tar_header (struct cpio_file_stat *file_hdr, int out_des)
134 {
135   int name_len;
136   union tar_record tar_rec;
137   struct tar_header *tar_hdr = (struct tar_header *) &tar_rec;
138 
139   memset (&tar_rec, 0, sizeof tar_rec);
140 
141   /* process_copy_out must ensure that file_hdr->c_name is short enough,
142      or we will lose here.  */
143 
144   name_len = strlen (file_hdr->c_name);
145   if (name_len <= TARNAMESIZE)
146     {
147       strncpy (tar_hdr->name, file_hdr->c_name, name_len);
148     }
149   else
150     {
151       /* Fit as much as we can into `name', the rest into `prefix'.  */
152       int prefix_len = split_long_name (file_hdr->c_name, name_len);
153 
154       strncpy (tar_hdr->prefix, file_hdr->c_name, prefix_len);
155       strncpy (tar_hdr->name, file_hdr->c_name + prefix_len + 1,
156 	       name_len - prefix_len - 1);
157     }
158 
159   /* Ustar standard (POSIX.1-1988) requires the mode to contain only 3 octal
160      digits */
161   TO_OCT (file_hdr, c_mode & MODE_ALL, 8, tar_hdr, mode);
162   TO_OCT (file_hdr, c_uid, 8, tar_hdr, uid);
163   TO_OCT (file_hdr, c_gid, 8, tar_hdr, gid);
164   TO_OCT (file_hdr, c_filesize, 12, tar_hdr, size);
165   TO_OCT (file_hdr, c_mtime, 12, tar_hdr, mtime);
166 
167   switch (file_hdr->c_mode & CP_IFMT)
168     {
169     case CP_IFREG:
170       if (file_hdr->c_tar_linkname)
171 	{
172 	  /* process_copy_out makes sure that c_tar_linkname is shorter
173 	     than TARLINKNAMESIZE.  */
174 	  strncpy (tar_hdr->linkname, file_hdr->c_tar_linkname,
175 		   TARLINKNAMESIZE);
176 	  tar_hdr->typeflag = LNKTYPE;
177 	  to_ascii (tar_hdr->size, 0, 12, LG_8, true);
178 	}
179       else
180 	tar_hdr->typeflag = REGTYPE;
181       break;
182     case CP_IFDIR:
183       tar_hdr->typeflag = DIRTYPE;
184       break;
185     case CP_IFCHR:
186       tar_hdr->typeflag = CHRTYPE;
187       break;
188     case CP_IFBLK:
189       tar_hdr->typeflag = BLKTYPE;
190       break;
191 #ifdef CP_IFIFO
192     case CP_IFIFO:
193       tar_hdr->typeflag = FIFOTYPE;
194       break;
195 #endif /* CP_IFIFO */
196 #ifdef CP_IFLNK
197     case CP_IFLNK:
198       tar_hdr->typeflag = SYMTYPE;
199       /* process_copy_out makes sure that c_tar_linkname is shorter
200 	 than TARLINKNAMESIZE.  */
201       strncpy (tar_hdr->linkname, file_hdr->c_tar_linkname,
202 	       TARLINKNAMESIZE);
203       to_ascii (tar_hdr->size, 0, 12, LG_8, true);
204       break;
205 #endif /* CP_IFLNK */
206     }
207 
208   if (archive_format == arf_ustar)
209     {
210       char *name;
211 
212       strncpy (tar_hdr->magic, TMAGIC, TMAGLEN);
213       strncpy (tar_hdr->version, TVERSION, TVERSLEN);
214 
215       name = getuser (file_hdr->c_uid);
216       if (name)
217 	strcpy (tar_hdr->uname, name);
218       name = getgroup (file_hdr->c_gid);
219       if (name)
220 	strcpy (tar_hdr->gname, name);
221 
222       TO_OCT (file_hdr, c_rdev_maj, 8, tar_hdr, devmajor);
223       TO_OCT (file_hdr, c_rdev_min, 8, tar_hdr, devminor);
224     }
225 
226   to_ascii (tar_hdr->chksum, tar_checksum (tar_hdr), 8, LG_8, true);
227 
228   tape_buffered_write ((char *) &tar_rec, out_des, TARRECORDSIZE);
229 
230   return 0;
231 }
232 
233 /* Return nonzero iff all the bytes in BLOCK are NUL.
234    SIZE is the number of bytes to check in BLOCK; it must be a
235    multiple of sizeof (long).  */
236 
237 int
null_block(long * block,int size)238 null_block (long *block, int size)
239 {
240   register long *p = block;
241   register int i = size / sizeof (long);
242 
243   while (i--)
244     if (*p++)
245       return 0;
246   return 1;
247 }
248 
249 /* Read a tar header, including the file name, from file descriptor IN_DES
250    into FILE_HDR.  */
251 
252 void
read_in_tar_header(struct cpio_file_stat * file_hdr,int in_des)253 read_in_tar_header (struct cpio_file_stat *file_hdr, int in_des)
254 {
255   long bytes_skipped = 0;
256   int warned = false;
257   union tar_record tar_rec;
258   struct tar_header *tar_hdr = (struct tar_header *) &tar_rec;
259   uid_t *uidp;
260   gid_t *gidp;
261 
262   tape_buffered_read ((char *) &tar_rec, in_des, TARRECORDSIZE);
263 
264   /* Check for a block of 0's.  */
265   if (null_block ((long *) &tar_rec, TARRECORDSIZE))
266     {
267 #if 0
268       /* Found one block of 512 0's.  If the next block is also all 0's
269 	 then this is the end of the archive.  If not, assume the
270 	 previous block was all corruption and continue reading
271 	 the archive.  */
272       /* Commented out because GNU tar sometimes creates archives with
273 	 only one block of 0's at the end.  This happened for the
274 	 cpio 2.0 distribution!  */
275       tape_buffered_read ((char *) &tar_rec, in_des, TARRECORDSIZE);
276       if (null_block ((long *) &tar_rec, TARRECORDSIZE))
277 #endif
278 	{
279 	  cpio_set_c_name (file_hdr, CPIO_TRAILER_NAME);
280 	  return;
281 	}
282 #if 0
283       bytes_skipped = TARRECORDSIZE;
284 #endif
285     }
286 
287   while (1)
288     {
289       file_hdr->c_chksum = FROM_OCTAL (tar_hdr->chksum);
290 
291       if (file_hdr->c_chksum != tar_checksum (tar_hdr))
292 	{
293 	  /* If the checksum is bad, skip 1 byte and try again.  When
294 	     we try again we do not look for an EOF record (all zeros),
295 	     because when we start skipping bytes in a corrupted archive
296 	     the chances are pretty good that we might stumble across
297 	     2 blocks of 512 zeros (that probably is not really the last
298 	     record) and it is better to miss the EOF and give the user
299 	     a "premature EOF" error than to give up too soon on a corrupted
300 	     archive.  */
301 	  if (!warned)
302 	    {
303 	      error (0, 0, _("invalid header: checksum error"));
304 	      warned = true;
305 	    }
306 	  memmove (&tar_rec, ((char *) &tar_rec) + 1, TARRECORDSIZE - 1);
307 	  tape_buffered_read (((char *) &tar_rec) + (TARRECORDSIZE - 1), in_des, 1);
308 	  ++bytes_skipped;
309 	  continue;
310 	}
311 
312       if (archive_format != arf_ustar)
313         cpio_set_c_name (file_hdr, stash_tar_filename (NULL, tar_hdr->name));
314       else
315         cpio_set_c_name (file_hdr, stash_tar_filename (tar_hdr->prefix,
316                                                       tar_hdr->name));
317 
318       file_hdr->c_nlink = 1;
319       file_hdr->c_mode = FROM_OCTAL (tar_hdr->mode);
320       file_hdr->c_mode = file_hdr->c_mode & 07777;
321   /* Debian hack: This version of cpio uses the -n flag also to extract
322      tar archives using the numeric UID/GID instead of the user/group
323      names in /etc/passwd and /etc/groups.  (98/10/15) -BEM */
324       if (archive_format == arf_ustar && !numeric_uid
325 	  && (uidp = getuidbyname (tar_hdr->uname)))
326 	file_hdr->c_uid = *uidp;
327       else
328 	file_hdr->c_uid = FROM_OCTAL (tar_hdr->uid);
329 
330       if (archive_format == arf_ustar && !numeric_uid
331 	  && (gidp = getgidbyname (tar_hdr->gname)))
332 	file_hdr->c_gid = *gidp;
333       else
334 	file_hdr->c_gid = FROM_OCTAL (tar_hdr->gid);
335       file_hdr->c_filesize = FROM_OCTAL (tar_hdr->size);
336       file_hdr->c_mtime = FROM_OCTAL (tar_hdr->mtime);
337       file_hdr->c_rdev_maj = FROM_OCTAL (tar_hdr->devmajor);
338       file_hdr->c_rdev_min = FROM_OCTAL (tar_hdr->devminor);
339       file_hdr->c_tar_linkname = NULL;
340 
341       switch (tar_hdr->typeflag)
342 	{
343 	case REGTYPE:
344 	case CONTTYPE:		/* For now, punt.  */
345 	default:
346 	  file_hdr->c_mode |= CP_IFREG;
347 	  break;
348 	case DIRTYPE:
349 	  file_hdr->c_mode |= CP_IFDIR;
350 	  break;
351 	case CHRTYPE:
352 	  file_hdr->c_mode |= CP_IFCHR;
353 	  /* If a POSIX tar header has a valid linkname it's always supposed
354 	     to set typeflag to be LNKTYPE.  System V.4 tar seems to
355 	     be broken, and for device files with multiple links it
356 	     puts the name of the link into linkname, but leaves typeflag
357 	     as CHRTYPE, BLKTYPE, FIFOTYPE, etc.  */
358 	  file_hdr->c_tar_linkname = stash_tar_linkname (tar_hdr->linkname);
359 
360 	  /* Does POSIX say that the filesize must be 0 for devices?  We
361 	     assume so, but HPUX's POSIX tar sets it to be 1 which causes
362 	     us problems (when reading an archive we assume we can always
363 	     skip to the next file by skipping filesize bytes).  For
364 	     now at least, it's easier to clear filesize for devices,
365 	     rather than check everywhere we skip in copyin.c.  */
366 	  file_hdr->c_filesize = 0;
367 	  break;
368 	case BLKTYPE:
369 	  file_hdr->c_mode |= CP_IFBLK;
370 	  file_hdr->c_tar_linkname = stash_tar_linkname (tar_hdr->linkname);
371 	  file_hdr->c_filesize = 0;
372 	  break;
373 #ifdef CP_IFIFO
374 	case FIFOTYPE:
375 	  file_hdr->c_mode |= CP_IFIFO;
376 	  file_hdr->c_tar_linkname = stash_tar_linkname (tar_hdr->linkname);
377 	  file_hdr->c_filesize = 0;
378 	  break;
379 #endif
380 	case SYMTYPE:
381 #ifdef CP_IFLNK
382 	  file_hdr->c_mode |= CP_IFLNK;
383 	  file_hdr->c_tar_linkname = stash_tar_linkname (tar_hdr->linkname);
384 	  file_hdr->c_filesize = 0;
385 	  break;
386 	  /* Else fall through.  */
387 #endif
388 	case LNKTYPE:
389 	  file_hdr->c_mode |= CP_IFREG;
390 	  file_hdr->c_tar_linkname = stash_tar_linkname (tar_hdr->linkname);
391 	  file_hdr->c_filesize = 0;
392 	  break;
393 
394 	case AREGTYPE:
395 	  /* Old tar format; if the last char in filename is '/' then it is
396 	     a directory, otherwise it's a regular file.  */
397 	  if (file_hdr->c_name[file_hdr->c_namesize - 1] == '/')
398 	    file_hdr->c_mode |= CP_IFDIR;
399 	  else
400 	    file_hdr->c_mode |= CP_IFREG;
401 	  break;
402 	}
403       break;
404     }
405   if (bytes_skipped > 0)
406     warn_junk_bytes (bytes_skipped);
407 }
408 
409 /* Return
410    2 if BUF is a valid POSIX tar header (the checksum is correct
411    and it has the "ustar" magic string),
412    1 if BUF is a valid old tar header (the checksum is correct),
413    0 otherwise.  */
414 
415 int
is_tar_header(char * buf)416 is_tar_header (char *buf)
417 {
418   struct tar_header *tar_hdr = (struct tar_header *) buf;
419   unsigned long chksum;
420 
421   chksum = FROM_OCTAL (tar_hdr->chksum);
422 
423   if (chksum != tar_checksum (tar_hdr))
424     return 0;
425 
426   /* GNU tar 1.10 and previous set the magic field to be "ustar " instead
427      of "ustar\0".  Only look at the first 5 characters of the magic
428      field so we can recognize old GNU tar ustar archives.  */
429   if (!strncmp (tar_hdr->magic, TMAGIC, TMAGLEN - 1))
430       return 2;
431   return 1;
432 }
433 
434 /* Return true if the filename is too long to fit in a tar header.
435    For old tar headers, if the filename's length is less than or equal
436    to 100 then it will fit, otherwise it will not.  For POSIX tar headers,
437    if the filename's length is less than or equal to 100 then it
438    will definitely fit, and if it is greater than 256 then it
439    will definitely not fit.  If the length is between 100 and 256,
440    then the filename will fit only if it is possible to break it
441    into a 155 character "prefix" and 100 character "name".  There
442    must be a slash between the "prefix" and the "name", although
443    the slash is not stored or counted in either the "prefix" or
444    the "name", and there must be at least one character in both
445    the "prefix" and the "name".  If it is not possible to break down
446    the filename like this then it will not fit.  */
447 
448 int
is_tar_filename_too_long(char * name)449 is_tar_filename_too_long (char *name)
450 {
451   int whole_name_len;
452   int prefix_name_len;
453 
454   whole_name_len = strlen (name);
455   if (whole_name_len <= TARNAMESIZE)
456     return false;
457 
458   if (archive_format != arf_ustar)
459     return true;
460 
461   if (whole_name_len > TARNAMESIZE + TARPREFIXSIZE + 1)
462     return true;
463 
464   /* See whether we can split up the name into acceptably-sized
465      `prefix' and `name' (`p') pieces. */
466   prefix_name_len = split_long_name (name, whole_name_len);
467 
468   /* Interestingly, a name consisting of a slash followed by
469      TARNAMESIZE characters can't be stored, because the prefix
470      would be empty, and thus ignored.  */
471   if (prefix_name_len == 0
472       || whole_name_len - prefix_name_len - 1 > TARNAMESIZE)
473     return true;
474 
475   return false;
476 }
477