Blob Blame History Raw
From: Phillip Lougher <phillip@squashfs.org.uk>
Date: Thu, 22 Nov 2012 04:58:39 +0000 (+0000)
Subject: unsquashfs: fix CVE-2012-4024
X-Git-Url: http://squashfs.git.sourceforge.net/git/gitweb.cgi?p=squashfs%2Fsquashfs;a=commitdiff_plain;h=19c38fba0be1ce949ab44310d7f49887576cc123;hp=f7bbe5a202648b505879e2570672c012498f31fb

unsquashfs: fix CVE-2012-4024

Fix potential stack overflow in get_component() where an individual
pathname component in an extract file (specified on the command line
or in an extract file) could exceed the 1024 byte sized targname
allocated on the stack.

Fix by dynamically allocating targname rather than storing it as
a fixed size on the stack.

Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
---

diff --git a/squashfs-tools/unsquashfs.c b/squashfs-tools/unsquashfs.c
index 90ed1c2..d9d1377 100644
--- a/squashfs-tools/unsquashfs.c
+++ b/squashfs-tools/unsquashfs.c
@@ -1099,15 +1099,18 @@ void squashfs_closedir(struct dir *dir)
 }
 
 
-char *get_component(char *target, char *targname)
+char *get_component(char *target, char **targname)
 {
+	char *start;
+
 	while(*target == '/')
 		target ++;
 
+	start = target;
 	while(*target != '/' && *target!= '\0')
-		*targname ++ = *target ++;
+		target ++;
 
-	*targname = '\0';
+	*targname = strndup(start, target - start);
 
 	return target;
 }
@@ -1133,12 +1136,12 @@ void free_path(struct pathname *paths)
 
 struct pathname *add_path(struct pathname *paths, char *target, char *alltarget)
 {
-	char targname[1024];
+	char *targname;
 	int i, error;
 
 	TRACE("add_path: adding \"%s\" extract file\n", target);
 
-	target = get_component(target, targname);
+	target = get_component(target, &targname);
 
 	if(paths == NULL) {
 		paths = malloc(sizeof(struct pathname));
@@ -1162,7 +1165,7 @@ struct pathname *add_path(struct pathname *paths, char *target, char *alltarget)
 			sizeof(struct path_entry));
 		if(paths->name == NULL)
 			EXIT_UNSQUASH("Out of memory in add_path\n");	
-		paths->name[i].name = strdup(targname);
+		paths->name[i].name = targname;
 		paths->name[i].paths = NULL;
 		if(use_regex) {
 			paths->name[i].preg = malloc(sizeof(regex_t));
@@ -1195,6 +1198,8 @@ struct pathname *add_path(struct pathname *paths, char *target, char *alltarget)
 		/*
 		 * existing matching entry
 		 */
+		free(targname);
+
 		if(paths->name[i].paths == NULL) {
 			/*
 			 * No sub-directory which means this is the leaf