Page MenuHomePhabricator

update tar
Closed, ResolvedPublic

Description

  • CVE-2018-20482
  • Check for reported regressions
  • Review: check the actually fix patches to ensure that the are sound
  • Review: Ensure correct patches have been backported and are applied e.g. debdiff
  • check reverse dependencies services which may need restarts i.e. debdeploy query_deps --packages libgd3 -s all
  • build debdeploy spec file i.e. generate-debdeploy-spec
  • deploy to canaries
  • deploy to fleet
  • confirm restarts with debdeploy

https://lists.debian.org/debian-lts-announce/2018/12/msg00023.html
https://security-tracker.debian.org/tracker/CVE-2018-20482

Event Timeline

jessie

DebDiff Report
diff -Nru tar-1.27.1/debian/changelog tar-1.27.1/debian/changelog
-- tar-1.27.1/debian/changelog  2016-10-30 06:48:55.000000000 +0000
++ tar-1.27.1/debian/changelog  2018-12-31 09:29:20.000000000 +0000
@ -1,3 +1,11 @@
tar (1.27.1-2+deb8u2) jessie-security; urgency=high
+
  * CVE-2018-20482: Fix a potential denial of service vulnerability where
    --sparse can loop endlessly if the file shrinks whilst it is being read.
    (Closes: #917377)
+
 -- Chris Lamb <lamby@debian.org>  Mon, 31 Dec 2018 09:26:14 +0000
+
tar (1.27.1-2+deb8u1) jessie-security; urgency=high
 
  * Non-maintainer upload by the Security Team.
iff -Nru tar-1.27.1/debian/patches/CVE-2018-20482.patch tar-1.27.1/debian/patches/CVE-2018-20482.patch
-- tar-1.27.1/debian/patches/CVE-2018-20482.patch       1970-01-01 01:00:00.000000000 +0100
++ tar-1.27.1/debian/patches/CVE-2018-20482.patch       2018-12-31 09:35:52.000000000 +0000
@ -0,0 +1,92 @@
--- tar-1.27.1.orig/src/sparse.c
+++ tar-1.27.1/src/sparse.c
@@ -321,6 +321,30 @@ sparse_dump_region (struct tar_sparse_fi
                             bufsize);
          return false;
        }
+      else if (bytes_read == 0)
+       {
+         char buf[UINTMAX_STRSIZE_BOUND];
+         struct stat st;
+         size_t n;
+         if (fstat (file->fd, &st) == 0)
+           n = file->stat_info->stat.st_size - st.st_size;
+         else
+           n = file->stat_info->stat.st_size
+             - (file->stat_info->sparse_map[i].offset
+                + file->stat_info->sparse_map[i].numbytes
+                - bytes_left);
++        
+         WARNOPT (WARN_FILE_SHRANK,
+                  (0, 0,
+                   ngettext ("%s: File shrank by %s byte; padding with zeros",
+                             "%s: File shrank by %s bytes; padding with zeros",
+                             n),
+                   quotearg_colon (file->stat_info->orig_file_name),
+                   STRINGIFY_BIGINT (n, buf)));
+         if (! ignore_failed_read_option)
+           set_exit_status (TAREXIT_DIFFERS);
+         return false;
+       }
+ 
       memset (blk->buffer + bytes_read, 0, BLOCKSIZE - bytes_read);
       bytes_left -= bytes_read;
@@ -358,9 +382,9 @@ sparse_extract_region (struct tar_sparse
          return false;
        }
       set_next_block_after (blk);
+      file->dumped_size += BLOCKSIZE;
       count = blocking_write (file->fd, blk->buffer, wrbytes);
       write_size -= count;
-      file->dumped_size += count;
       mv_size_left (file->stat_info->archive_file_size - file->dumped_size);
       file->offset += count;
       if (count != wrbytes)
@@ -492,6 +516,11 @@ check_sparse_region (struct tar_sparse_f
                             rdsize);
          return false;
        }
+      else if (bytes_read == 0)
+       {
+         report_difference (file->stat_info, _("Size differs"));
+         return false;
+       }
       if (!zero_block_p (diff_buffer, bytes_read))
        {
          char begbuf[INT_BUFSIZE_BOUND (off_t)];
@@ -1108,6 +1137,8 @@ pax_decode_header (struct tar_sparse_fil
       char *p;
       size_t i;
+ 
+      off_t start;
++
 #define COPY_BUF(b,buf,src) do                                     \
  {                                                                 \
    char *endp = b->buffer + BLOCKSIZE;                             \
@@ -1123,7 +1154,6 @@ pax_decode_header (struct tar_sparse_fil
        if (src == endp)                                            \
         {                                                         \
           set_next_block_after (b);                               \
-           file->dumped_size += BLOCKSIZE;                         \
            b = find_next_block ();                                 \
            src = b->buffer;                                        \
           endp = b->buffer + BLOCKSIZE;                           \
@@ -1134,8 +1164,8 @@ pax_decode_header (struct tar_sparse_fil
    dst[-1] = 0;                                                    \
  } while (0)
+ 
+      start = current_block_ordinal ();
       set_next_block_after (current_header);
-      file->dumped_size += BLOCKSIZE;
       blk = find_next_block ();
       p = blk->buffer;
       COPY_BUF (blk,nbuf,p);
@@ -1172,6 +1202,8 @@ pax_decode_header (struct tar_sparse_fil
          sparse_add_map (file->stat_info, &sp);
        }
       set_next_block_after (blk);
++
+      file->dumped_size += BLOCKSIZE * (current_block_ordinal () - start);
     }
+ 
   return true;
iff -Nru tar-1.27.1/debian/patches/series tar-1.27.1/debian/patches/series
--- tar-1.27.1/debian/patches/series    2016-10-30 06:48:55.000000000 +0000
+++ tar-1.27.1/debian/patches/series    2018-12-31 09:30:11.000000000 +0000
@ -1,3 +1,4 @@
 pristine-tar.diff
 listed03-linux-only
 When-extracting-skip-.-members.patch
+CVE-2018-20482.patch
Bug Report
  • 2019-01-16 17:15:02: [919493] tar: ships empty /usr/lib/tar/

bug 919493 dose not affect jessie

patch is missing additional tests but this is not an issue