Просмотр исходного кода

SA-2003.033-infozip; CAN-2003-0282

Thomas Lotterer 23 лет назад
Родитель
Сommit
6891e77779
1 измененных файлов с 87 добавлено и 0 удалено
  1. 87 0
      infozip/infozip.patch

+ 87 - 0
infozip/infozip.patch

@@ -9,3 +9,90 @@
      [ $? -eq 0 ] && CPP="${CPP} -DNO_UNDERLINE"
      if eval "$CPP crc_i386.S > _crc_i386.s 2>/dev/null"; then
        if eval "$CC -c _crc_i386.s >/dev/null 2>/dev/null" && [ -f _crc_i386.o ]
+
+http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2003-0282
+    Directory traversal vulnerability in UnZip 5.50 allows attackers to
+    overwrite arbitrary files via invalid characters between two . (dot)
+    characters, which are filtered and result in a ".." sequence.
+
+--- unzip-5.50/unix/unix.c.orig	2002-01-21 17:54:42.000000000 -0500
++++ unzip-5.50/unix/unix.c	2003-06-11 18:35:38.000000000 -0400
+@@ -421,7 +421,8 @@
+  */
+ {
+     char pathcomp[FILNAMSIZ];      /* path-component buffer */
+-    char *pp, *cp=(char *)NULL;    /* character pointers */
++    char *pp, *cp=(char *)NULL,    /* character pointers */
++         *dp=(char *)NULL;
+     char *lastsemi=(char *)NULL;   /* pointer to last semi-colon in pathcomp */
+ #ifdef ACORN_FTYPE_NFS
+     char *lastcomma=(char *)NULL;  /* pointer to last comma in pathcomp */
+@@ -429,6 +430,7 @@
+ #endif
+     int quote = FALSE;             /* flags */
+     int killed_ddot = FALSE;       /* is set when skipping "../" pathcomp */
++    int snarf_ddot = FALSE;	   /* Is set while scanning for "../" */
+     int error = MPN_OK;
+     register unsigned workch;      /* hold the character being tested */
+ 
+@@ -467,6 +469,9 @@
+     while ((workch = (uch)*cp++) != 0) {
+ 
+         if (quote) {                 /* if character quoted, */
++	    if ((pp == pathcomp) && (workch == '.'))
++		/* Oh no you don't... */
++		goto ddot_hack;
+             *pp++ = (char)workch;    /*  include it literally */
+             quote = FALSE;
+         } else
+@@ -481,15 +486,44 @@
+                 break;
+ 
+             case '.':
+-                if (pp == pathcomp) {   /* nothing appended yet... */
++                if (pp == pathcomp) {
++ddot_hack:
++		    /* nothing appended yet... */
+                     if (*cp == '/') {   /* don't bother appending "./" to */
+                         ++cp;           /*  the path: skip behind the '/' */
+                         break;
+-                    } else if (!uO.ddotflag && *cp == '.' && cp[1] == '/') {
+-                        /* "../" dir traversal detected */
+-                        cp += 2;        /*  skip over behind the '/' */
+-                        killed_ddot = TRUE; /*  set "show message" flag */
+-                        break;
++                    } else if (!uO.ddotflag) {
++
++			/*
++			 * SECURITY: Skip past control characters if the user
++			 * didn't OK use of absolute pathnames. lhh - this is
++			 * a very quick, ugly, inefficient fix.
++			 */
++			dp = cp;
++			do {
++			    workch = (uch)(*dp);
++			    if (workch == '/' && snarf_ddot) {
++                                /* "../" dir traversal detected */
++                                cp = dp + 1;      /* skip past the '/' */
++                                killed_ddot = TRUE; /* set "show msg" flag */
++                                break;
++                            } else if (workch == '.' && !snarf_ddot) {
++				snarf_ddot = TRUE;
++                	    } else if (isprint(workch) ||
++				       ((workch > 127) && (workch <= 254))) {
++				/*
++				 * Since we found a printable, non-ctrl char,
++				 * we can stop looking for '../', the amount
++				 * in ../!
++				 */
++			        break;
++			    }
++
++			    dp++;
++                        } while (*dp != 0);
++
++			if (killed_ddot)
++			    break;
+                     }
+                 }
+                 *pp++ = '.';