$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