Subject: Allowing directory traversal or not in fastjar
To: None <tech-pkg@netbsd.org>
From: None <joerg@britannica.bec.de>
List: tech-pkg
Date: 03/07/2006 10:49:11
--OgqxwSJOaUobr8KG
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi all,
the attached patch removes the support for directory traversal from
fastjar by enforcing strict normalisation. This is *not* done with
realpath, since that could resolve e.g. symlinks as well, resulting in
possibly unwanted behaviour.

My question is whether we want this behaviour, want it optional or
whether I should look for a different fix.

Joerg

--OgqxwSJOaUobr8KG
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="fastjar.diff"

? fastjar.diff
Index: distinfo
===================================================================
RCS file: /cvsroot/pkgsrc/archivers/fastjar/distinfo,v
retrieving revision 1.10
diff -u -r1.10 distinfo
--- distinfo	1 Dec 2005 17:01:25 -0000	1.10
+++ distinfo	7 Mar 2006 09:04:38 -0000
@@ -6,4 +6,4 @@
 SHA1 (patch-aa) = 12cc5397a89c18d239164caa3955121ca6d01de0
 SHA1 (patch-ab) = c13f46e1a3e60a3bbe656af609a5c9fb047a4ca3
 SHA1 (patch-ac) = ce8eefb978a93d0043f8b98fbf4049f022ce663c
-SHA1 (patch-ad) = 3d0a5c0afc02b1bee58c415f3b3f2691d0e0dcda
+SHA1 (patch-ad) = c988c11e01c364d94a7a12c3eb4dc933b12861a0
Index: patches/patch-ad
===================================================================
RCS file: /cvsroot/pkgsrc/archivers/fastjar/patches/patch-ad,v
retrieving revision 1.4
diff -u -r1.4 patch-ad
--- patches/patch-ad	1 Dec 2005 17:01:25 -0000	1.4
+++ patches/patch-ad	7 Mar 2006 09:04:38 -0000
@@ -1,9 +1,57 @@
-$NetBSD: patch-ad,v 1.4 2005/12/01 17:01:25 rillig Exp $
+$NetBSD$
 
---- jartool.c.orig	2001-01-11 00:38:15.000000000 -0800
+--- jartool.c.orig	2001-01-11 09:38:15.000000000 +0100
 +++ jartool.c
-@@ -171,4 +171,2 @@
+@@ -171,4 +171,2 @@ static char rcsid[] = "$Id: jartool.c,v 
  
 -extern int errno;
 -
  void usage(char*);
+@@ -1143,2 +1141,27 @@ int create_central_header(int fd){
+ 
++static void canonical_filename(char *filename)
++{
++    char *iterator, *iterator2;
++
++    for (;;) {
++	if (*filename == '/')
++	    memmove(filename, filename + 1, strlen(filename));
++	else if (filename[0] == '.' && filename[1] == '/')
++	    memmove(filename, filename + 2, strlen(filename) - 1);
++	else if (filename[0] == '.' && filename[1] == '.' && filename[2] == '/')
++	    memmove(filename, filename + 3, strlen(filename) - 2);
++	else if ((iterator = strstr(filename, "//")) != NULL)
++	    memmove(iterator, iterator + 1, strlen(iterator));
++	else if ((iterator = strstr(filename, "/./")) != NULL)
++	    memmove(iterator, iterator + 2, strlen(iterator) - 1);
++	else if ((iterator = strstr(filename, "/../")) != NULL) {
++	    for (iterator2 = iterator - 1; iterator2 > filename && *iterator2 != '/'; --iterator2)
++		continue;
++	    /* iterator2 >= filename, handle the initial slash above, if necessary */
++	    memmove(iterator2, iterator + 3, strlen(iterator) - 2);
++	} else
++	    break;
++    }
++}
++
+ int extract_jar(int fd, char **files, int file_num){
+@@ -1251,2 +1274,9 @@ int extract_jar(int fd, char **files, in
+ 
++     canonical_filename(filename);
++
++     if (*filename == '\0') {
++        fprintf(stderr, "Error extracting JAR archive, empty file name!\n");
++        exit(1);
++      }
++
+ #ifdef DEBUG    
+@@ -1563,2 +1593,9 @@ int list_jar(int fd, char **files, int f
+       filename[fnlen] = '\0';
++
++      canonical_filename(filename);
++      if (*filename == '\0') {
++          fprintf(stderr, "Error extracting JAR archive, empty file name!\n");
++          exit(1);
++      }
++
+     

--OgqxwSJOaUobr8KG--