pkgsrc-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: pkg/55684 (Absolute & relative directory traversal with archivers/zoo)



The following reply was made to PR pkg/55684; it has been noted by GNATS.

From: Martin Husemann <martin%duskware.de@localhost>
To: Benny Siegert <bsiegert%gmail.com@localhost>
Cc: gnats-bugs%netbsd.org@localhost, stegozor%gmail.com@localhost
Subject: Re: pkg/55684 (Absolute & relative directory traversal with
 archivers/zoo)
Date: Sun, 4 Oct 2020 12:35:45 +0200

 --9amGYk9869ThD9tj
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 I don't know how to *properly* deal with such broken archives, but the
 patch attached below makes extraction fail for me and should fix the
 traversal attack.
 
 The problem with the original Debian patch was that it did not convert
 all possible path fields in the directory structure (and the selection
 which of the fields to use was done after fixup by the patch).
 Instead this patch modifies the function intended for such local OS
 verifications.
 
 More eyes + more tests would be good.
 
 Martin
 
 --9amGYk9869ThD9tj
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: attachment; filename="patch-bsd.c"
 
 $NetBSD$
 
 Try to fix CVE id CAN-2005-2349
 
 --- bsd.c.orig	2020-10-04 11:43:19.820472893 +0200
 +++ bsd.c	2020-10-04 12:27:08.462546277 +0200
 @@ -39,6 +39,42 @@ legal for the host system.  It is used d
  char *fixfname(fname)
  char *fname;
  {
 +  /*
 +   * This is a (very loose) adaption of debian's 02-traversal-directory.patch,
 +   * but applied at the proper place.
 +   * THIS CODE WAS WRITTEN TO SOLVE PROBLEM WITH DIRECTORY TRAVERSAL SECURITY
 +   * BUG (CVE id CAN-2005-2349).
 +   */
 +
 +   char *p;
 +   size_t l;
 +
 +   /* remove all "../" inside filename */
 +   while ((p = strstr( fname, "../" )) != NULL) {
 +      l = strlen(p+3);
 +      if (l == 0)
 +        *p = 0;
 +      else
 +         memmove(p, p+3, l);
 +   }
 +
 +   /* remove all leading '/' */
 +   for (p = fname; *p == '/'; p++)
 +      ;
 +   l = strlen(p);
 +   if (l == 0)
 +      fname[0] = 0;
 +   else if (p == fname+1) {
 +      /* convert "/name" to "name" */
 +      memmove(fname, p, l);
 +      fname[l] = 0;
 +   } else if (p > fname+1) {
 +      /* convert "//name" to "./name" */
 +      fname[0] = '.';
 +      memmove(fname+1, p, l);
 +      fname[l+1] = 0;
 +   }
 +
     return fname; /* default is no-op */
  }
  
 
 --9amGYk9869ThD9tj--
 


Home | Main Index | Thread Index | Old Index