Blame SOURCES/fastjar-CVE-2010-0831.patch

25c7f1
2010-06-10  Jakub Jelinek  <jakub@redhat.com>
25c7f1
	    Dan Rosenberg  <dan.j.rosenberg@gmail.com>
25c7f1
25c7f1
	* jartool.c (extract_jar): Fix up checks for traversal to parent
25c7f1
	directories, disallow absolute paths, make the code slightly more
25c7f1
	efficient.
25c7f1
25c7f1
--- fastjar-0.97/jartool.c.jj	2009-09-07 00:10:47.000000000 +0200
25c7f1
+++ fastjar-0.97/jartool.c	2010-06-08 20:00:29.000000000 +0200
25c7f1
@@ -1730,7 +1730,17 @@ int extract_jar(int fd, const char **fil
25c7f1
       struct stat sbuf;
25c7f1
       int depth = 0;
25c7f1
 
25c7f1
-      tmp_buff = malloc(sizeof(char) * strlen((const char *)filename));
25c7f1
+      if(*filename == '/'){
25c7f1
+	fprintf(stderr, "Absolute path names are not allowed.\n");
25c7f1
+	exit(EXIT_FAILURE);
25c7f1
+      }
25c7f1
+
25c7f1
+      tmp_buff = malloc(strlen((const char *)filename));
25c7f1
+
25c7f1
+      if(tmp_buff == NULL) {
25c7f1
+	fprintf(stderr, "Out of memory.\n");
25c7f1
+	exit(EXIT_FAILURE);
25c7f1
+      }
25c7f1
 
25c7f1
       for(;;){
25c7f1
         const ub1 *idx = (const unsigned char *)strchr((const char *)start, '/');
25c7f1
@@ -1738,25 +1748,28 @@ int extract_jar(int fd, const char **fil
25c7f1
         if(idx == NULL)
25c7f1
           break;
25c7f1
         else if(idx == start){
25c7f1
+	  tmp_buff[idx - filename] = '/';
25c7f1
           start++;
25c7f1
           continue;
25c7f1
         }
25c7f1
-        start = idx + 1;
25c7f1
 
25c7f1
-        strncpy(tmp_buff, (const char *)filename, (idx - filename));
25c7f1
-        tmp_buff[(idx - filename)] = '\0';
25c7f1
+	memcpy(tmp_buff + (start - filename), (const char *)start, (idx - start));
25c7f1
+	tmp_buff[idx - filename] = '\0';
25c7f1
 
25c7f1
 #ifdef DEBUG    
25c7f1
         printf("checking the existance of %s\n", tmp_buff);
25c7f1
 #endif
25c7f1
-	if(strcmp(tmp_buff, "..") == 0){
25c7f1
+	if(idx - start == 2 && memcmp(start, "..", 2) == 0){
25c7f1
 	  --depth;
25c7f1
 	  if (depth < 0){
25c7f1
 	    fprintf(stderr, "Traversal to parent directories during unpacking!\n");
25c7f1
 	    exit(EXIT_FAILURE);
25c7f1
 	  }
25c7f1
-	} else if (strcmp(tmp_buff, ".") != 0)
25c7f1
+	} else if (idx - start != 1 || *start != '.')
25c7f1
 	  ++depth;
25c7f1
+
25c7f1
+        start = idx + 1;
25c7f1
+
25c7f1
         if(stat(tmp_buff, &sbuf) < 0){
25c7f1
           if(errno != ENOENT)
25c7f1
             exit_on_error("stat");
25c7f1
@@ -1765,6 +1778,7 @@ int extract_jar(int fd, const char **fil
25c7f1
 #ifdef DEBUG    
25c7f1
           printf("Directory exists\n");
25c7f1
 #endif
25c7f1
+	  tmp_buff[idx - filename] = '/';
25c7f1
           continue;
25c7f1
         }else {
25c7f1
           fprintf(stderr, "Hmmm.. %s exists but isn't a directory!\n",
25c7f1
@@ -1781,10 +1795,11 @@ int extract_jar(int fd, const char **fil
25c7f1
         if(verbose && handle)
25c7f1
           printf("%10s: %s/\n", "created", tmp_buff);
25c7f1
 
25c7f1
+	tmp_buff[idx - filename] = '/';
25c7f1
       }
25c7f1
 
25c7f1
       /* only a directory */
25c7f1
-      if(strlen((const char *)start) == 0)
25c7f1
+      if(*start == '\0')
25c7f1
         dir = TRUE;
25c7f1
 
25c7f1
 #ifdef DEBUG    
25c7f1
@@ -1792,7 +1807,7 @@ int extract_jar(int fd, const char **fil
25c7f1
 #endif
25c7f1
 
25c7f1
       /* If the entry was just a directory, don't write to file, etc */
25c7f1
-      if(strlen((const char *)start) == 0)
25c7f1
+      if(*start == '\0')
25c7f1
         f_fd = -1;
25c7f1
 
25c7f1
       free(tmp_buff);
25c7f1
@@ -1876,7 +1891,8 @@ int extract_jar(int fd, const char **fil
25c7f1
       exit(EXIT_FAILURE);
25c7f1
     }
25c7f1
 
25c7f1
-    close(f_fd);
25c7f1
+    if (f_fd != -1)
25c7f1
+      close(f_fd);
25c7f1
 
25c7f1
     if(verbose && dir == FALSE && handle)
25c7f1
       printf("%10s: %s\n",