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