summaryrefslogtreecommitdiff
path: root/archivers/fastjar/patches/patch-ad
blob: 2b15ccef20c196589e6bdf5977bc2b5816d5bd68 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
$NetBSD: patch-ad,v 1.7 2016/03/05 15:08:30 bsiegert Exp $

date: 2006-03-14 23:02:01 +0900;  author: joerg;  state: Exp;  lines: +51 -3;
Normalise path names as relative under cwd as if they would have been
extracted under chroot. Don't attempt to deal with existing symlinks
to directories. This prevents directory traversal and therefore the
creation of arbitrary files. Bump revision.
     
--- jartool.c.orig	2009-09-07 07:10:47.000000000 +0900
+++ jartool.c	2014-12-15 18:35:25.000000000 +0900
@@ -1512,6 +1512,31 @@ int create_central_header(int fd){
   return 0;
 }
 
+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, const char **files, int file_num){
   size_t rdamt;
   int out_a, in_a;
@@ -1628,6 +1653,13 @@ int extract_jar(int fd, const char **fil
     pb_read(&pbf, filename, fnlen);
     filename[fnlen] = '\0';
 
+    canonical_filename(filename);
+
+    if (*filename == '\0') {
+	 fprintf(stderr, "Error extracting JAR archive, empty file name!\n");
+	 exit(1);
+     }
+
 #ifdef DEBUG    
     printf("filename is %s\n", filename);
 #endif