SOURCES: unzoo-directory_traversal.patch (NEW) - new (borrowed fro...
adamg
adamg at pld-linux.org
Mon Apr 17 16:37:00 CEST 2006
Author: adamg Date: Mon Apr 17 14:37:00 2006 GMT
Module: SOURCES Tag: HEAD
---- Log message:
- new (borrowed from Debian)
---- Files affected:
SOURCES:
unzoo-directory_traversal.patch (NONE -> 1.1) (NEW)
---- Diffs:
================================================================
Index: SOURCES/unzoo-directory_traversal.patch
diff -u /dev/null SOURCES/unzoo-directory_traversal.patch:1.1
--- /dev/null Mon Apr 17 16:37:00 2006
+++ SOURCES/unzoo-directory_traversal.patch Mon Apr 17 16:36:54 2006
@@ -0,0 +1,225 @@
+--- unzoo-4.4.orig/unzoo.c
++++ unzoo-4.4/unzoo.c
+@@ -245,6 +245,13 @@
+ */
+ #include <stdio.h>
+
++#ifdef SYS_IS_UNIX
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <string.h>
++#include <stdlib.h>
++#include <utime.h>
++#endif
+
+ /****************************************************************************
+ **
+@@ -613,8 +620,8 @@
+ ** members with the correct time as stored in the archive.
+ */
+ #ifdef SYS_IS_UNIX
+-unsigned int Secs [2];
+-#define SETF_TIME(patl,secs) (Secs[0]=Secs[1]=(secs),!utime((patl),Secs))
++struct utimbuf Secs;
++#define SETF_TIME(patl,secs) (Secs.actime=Secs.modtime=(secs),!utime((patl),&Secs))
+ #endif
+ #ifdef SYS_IS_DOS_DJGPP
+ unsigned long Secs [2];
+@@ -1265,10 +1272,12 @@
+ /* try to match the name part */
+ while ( *pat != '\0' || *str != '\0' ) {
+ if ( *pat==*str ) { pat++; str++; }
+- else if ( *pat=='?' && ! IsSpec[*str] ) { pat++; str++; }
++ else if ( *pat=='?' && ! IsSpec[(unsigned int)*str] )
++ { pat++; str++; }
+ else if ( *pat=='?' && *str != '\0' ) { pat++; str++; }
+ else if ( *pat=='*' ) { pos = ++pat; tmp = str; }
+- else if ( tmp != 0 && ! IsSpec[*tmp] ) { pat = pos; str = ++tmp; }
++ else if ( tmp != 0 && ! IsSpec[(unsigned int)*tmp] )
++ { pat = pos; str = ++tmp; }
+ else break;
+ }
+ return *pat == '\0' && *str == '\0';
+@@ -2470,7 +2479,7 @@
+
+ /****************************************************************************
+ **
+-*F ExtrArch(<bim>,<out>,<ovr>,<pre>,<arc>,<filec>,<files>) . extract members
++*F ExtrArch(<bim>,<out>,<ovr>,<pre>,<frc>,<arc>,<filec>,<files>) . extract members
+ **
+ ** 'ExtrArch' extracts the members of the archive with the name <arc> that
+ ** match one of the file name patterns '<files>[0] .. <files>[<filec>-1]'.
+@@ -2482,12 +2491,15 @@
+ ** stdout, i.e., to the screen. and if it is 2, the members are extracted.
+ ** If <ovr> is 0, members will not overwrite existing files; otherwise they
+ ** will. <pre> is a prefix that is prepended to all path names.
++** <frc> is 1 if the user requested extraction of members even if this would
++** result in a directory traversal.
+ */
+-int ExtrArch ( bim, out, ovr, pre, arc, filec, files )
++int ExtrArch ( bim, out, ovr, pre, frc, arc, filec, files )
+ unsigned long bim;
+ unsigned long out;
+ unsigned long ovr;
+ char * pre;
++ unsigned long frc;
+ char * arc;
+ unsigned long filec;
+ char * files [];
+@@ -2573,6 +2585,102 @@
+ continue;
+ }
+
++ /* check the path for directory traversal */
++ if (frc != 1) {
++ /* but only if the user did not request otherwise */
++
++ /* building the universal path of this member */
++ char patu [sizeof(Entry.diru) + sizeof(Entry.namu) + 2];
++ strcpy( patu, Entry.diru );
++ if ( strlen(patu) && patu[strlen(patu)-1] != '/') strcat( patu, "/" );
++ strcat( patu, (Entry.lnamu ? Entry.namu : Entry.nams) );
++
++ int found_trav = 0;
++
++ if ( strstr( patu, "/../" )) {
++ found_trav = 1;
++
++ /* remove "/../" from the path */
++ char tmp [sizeof(patu)];
++ char *p;
++ char *q;
++ memset(tmp, 0, sizeof(tmp));
++ q = patu;
++
++ while ( !strncmp(q, "/../", 4) ) {
++ q += 3;
++ }
++ if (q[0] == '/') q++;
++
++ while ((p = strstr( q, "/../" )) != NULL) {
++ if (q[0] == '/') q++;
++ if (p > q) strncat(tmp, q, p-q);
++ if (tmp[strlen(tmp)-1] != '/') strcat(tmp, "/");
++ p += 3;
++ q = p;
++ }
++ strncat(tmp, q+1, patu + strlen(patu) - q);
++ strcpy(patu, tmp);
++
++ printf("unzoo: skipped \"/../\" path component(s) in '%s'\n", Entry.patl);
++ }
++ if ( *patu == '/' && !strlen( pre ) ) {
++ found_trav = 1;
++
++ char *p = malloc(sizeof(patu));
++ char *q = p;
++ memset(p, 0, sizeof(patu));
++ strcpy(p, patu);
++ while ( q[0] == '/' ) q++;
++ strcpy(patu, q);
++ free(p);
++
++ printf("unzoo: skipped root directory path component in '%s'\n", patl);
++ }
++ if ( !strncmp( patu, "../", 3 )) {
++ found_trav = 1;
++
++ char tmp [sizeof(patu)];
++ memset(tmp, 0, sizeof(tmp));
++ strcpy(tmp, patu + 3);
++ strcpy(patu, tmp);
++
++ printf("unzoo: skipped \"../\" path component in '%s'\n", patl);
++ }
++
++ if (found_trav) {
++ /* patu contains the sanitized 'universal' path, i.e. */
++ /* separated by '/' characters, including the file name. */
++
++ char *f = strrchr( patu, '/' );
++ *f++ = '\0';
++ /* Now, patu points to the directory part, f to the file */
++
++ memset( Entry.diru, 0, sizeof(Entry.diru) );
++ strncpy( Entry.diru, patu, sizeof(Entry.diru)-1 );
++ if ( Entry.lnamu > 0 ) {
++ memset( Entry.namu, 0, sizeof(Entry.namu) );
++ strncpy( Entry.namu, f, sizeof(Entry.namu)-1 );
++ } else {
++ memset( Entry.nams, 0, sizeof(Entry.nams) );
++ strncpy( Entry.nams, f, sizeof(Entry.nams)-1 );
++ }
++
++ /* convert the names to local format */
++ if ( Entry.system == 0 || Entry.system == 2 ) {
++ CONV_DIRE( Entry.dirl, Entry.diru );
++ CONV_NAME( Entry.naml, (Entry.lnamu ? Entry.namu : Entry.nams) );
++ }
++ else {
++ strcpy( Entry.dirl, Entry.diru );
++ strcpy( Entry.naml, (Entry.lnamu ? Entry.namu : Entry.nams) );
++ }
++ /* sizeof(patl)=512, sizeof({dirl|naml}=256} */
++ strcpy( Entry.patl, Entry.dirl );
++ strcat( Entry.patl, Entry.naml );
++ }
++ }
++
+ /* check that such a file does not already exist */
+ strcpy( patl, pre ); strcat( patl, Entry.patl );
+ if ( out == 2 && ovr == 0 && OpenReadFile(patl,0L) ) {
+@@ -2731,7 +2839,7 @@
+ printf(" <file>: list only files matching at least one pattern,\n");
+ printf(" '?' matches any char, '*' matches any string.\n");
+ printf("\n");
+- printf("unzoo -x [-abnpo] [-j <prefix>] <archive>[.zoo] [<file>..]\n");
++ printf("unzoo -x [-abnpo] [-t] [-j <prefix>] <archive>[.zoo] [<file>..]\n");
+ printf(" extract the members of the archive\n");
+ printf(" -a: extract all members as text files ");
+ printf("(not only those with !TEXT! comments)\n");
+@@ -2741,6 +2849,10 @@
+ printf(" -p: extract to stdout\n");
+ printf(" -o: extract over existing files\n");
+ printf(" -j: extract to '<prefix><membername>'\n");
++ printf(" -f: force extraction of members to their original locations\n");
++ printf(" even if this results in files extracted outside the\n");
++ printf(" working directory. THIS COULD POTENTIALLY OVERWRITE\n");
++ printf(" IMPORTANT FILES, SO USE WITH CARE!\n");
+ printf(" <file>: extract only files matching at least one pattern,\n");
+ printf(" '?' matches any char, '*' matches any string.\n");
+ return 1;
+@@ -2764,6 +2876,7 @@
+ unsigned long bim; /* extraction mode option */
+ unsigned long out; /* output destination option */
+ unsigned long ovr; /* overwrite file option */
++ unsigned long frc; /* force extraction option */
+ char * pre; /* prefix to prepend to path names */
+ char argl [256]; /* interactive command line */
+ int argd; /* interactive command count */
+@@ -2783,7 +2896,7 @@
+ do {
+
+ /* scan the command line arguments */
+- cmd = 1; ver = 0; bim = 0; out = 2; ovr = 0;
++ cmd = 1; ver = 0; bim = 0; out = 2; ovr = 0; frc = 0;
+ pre = "";
+ while ( 1 < argc && argv[1][0] == '-' ) {
+ if ( argv[1][2] != '\0' ) cmd = 0;
+@@ -2793,6 +2906,7 @@
+ case 'x': case 'X': if ( cmd != 0 ) cmd = 2; break;
+ case 'a': case 'A': if ( cmd != 2 ) cmd = 0; bim = 1; break;
+ case 'b': case 'B': if ( cmd != 2 ) cmd = 0; bim = 2; break;
++ case 'f': case 'F': if ( cmd != 2 ) cmd = 0; frc = 1; break;
+ case 'n': case 'N': if ( cmd != 2 ) cmd = 0; out = 0; break;
+ case 'p': case 'P': if ( cmd != 2 ) cmd = 0; out = 1; break;
+ case 'o': case 'O': if ( cmd != 2 ) cmd = 0; ovr = 1; break;
+@@ -2809,7 +2923,7 @@
+ res = ListArch( ver, argv[1],
+ (unsigned long)argc-2, argv+2 );
+ else if ( cmd == 2 && 1 < argc )
+- res = ExtrArch( bim, out, ovr, pre, argv[1],
++ res = ExtrArch( bim, out, ovr, pre, frc, argv[1],
+ (unsigned long)argc-2, argv+2 );
+ else
+ res = HelpArch();
================================================================
More information about the pld-cvs-commit
mailing list