[LinuxBIOS] r453 - LinuxBIOSv3/util/lar

svn at openbios.org svn at openbios.org
Fri Jul 13 12:40:31 CEST 2007


Author: stuge
Date: 2007-07-13 12:40:31 +0200 (Fri, 13 Jul 2007)
New Revision: 453

Modified:
   LinuxBIOSv3/util/lar/extract.c
   LinuxBIOSv3/util/lar/lib.c
   LinuxBIOSv3/util/lar/lib.h
Log:
Replaces mkdirp() with mkdirp_below() that aborts directory creation and
returns an error if any part of dirpath is located outside the specified
parent directory. Use the parent "/" to allow new directories anywhere.
Note that dirpath is relative to the working directory, not to parent.

Signed-off-by: Peter Stuge <peter at stuge.se>
Acked-by: Stefan Reinauer <stepan at coresystems.de>


Modified: LinuxBIOSv3/util/lar/extract.c
===================================================================
--- LinuxBIOSv3/util/lar/extract.c	2007-07-12 20:03:02 UTC (rev 452)
+++ LinuxBIOSv3/util/lar/extract.c	2007-07-13 10:40:31 UTC (rev 453)
@@ -119,7 +119,7 @@
 		if (pos) {
 			pos[1] = 0;
 			/* printf("Pathname %s\n",pathname); */
-			mkdirp(pathname, 0755);
+			mkdirp_below(".", pathname, 0755);
 		}
 		free(pathname);
 

Modified: LinuxBIOSv3/util/lar/lib.c
===================================================================
--- LinuxBIOSv3/util/lar/lib.c	2007-07-12 20:03:02 UTC (rev 452)
+++ LinuxBIOSv3/util/lar/lib.c	2007-07-13 10:40:31 UTC (rev 453)
@@ -24,6 +24,7 @@
 #include <strings.h>
 #include <unistd.h>
 #include <dirent.h>
+#include <errno.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 
@@ -33,42 +34,82 @@
 
 static struct file *files = NULL;
 
-int mkdirp(const char *dirpath, mode_t mode)
+/**
+ * Create a new directory including any missing parent directories.
+ *
+ * NOTE: This function does not do complete path resolution as described in
+ * Linux path_resolution(2) and hence will fail for complex paths:
+ *
+ * e.g.: mkdirp_below("subdir", "subdir/../subdir/x", 0777);
+ *
+ * This call should create subdir/x, but since subdir/.. is outside subdir,
+ * the function returns an error.
+ *
+ * @param parent Return an error if a new directory would be created outside
+ * this directory. Pass "/" to allow new directories to be created anywhere.
+ * @param dirpath The new directory that should be created, the path can be
+ * either absolute or relative to the current working directory. (It is not
+ * relative to parent.)
+ * @param mode Permissions to use for newly created directories.
+ */
+int mkdirp_below(const char *parent, const char *dirpath, mode_t mode)
 {
-	char *pos, *currpath, *path;
-	char cwd[MAX_PATH];
-	int ret = 0;
+	int ret = -1;
+	size_t dirsep, parlen, sublen;
+	char c, *r, *path = NULL, *subdir, rpar[PATH_MAX], rsub[PATH_MAX];
 
+	if (!dirpath) {
+		fprintf(stderr, "mkdirp_below: No new directory specified\n");
+		goto done;
+	}
+
 	path = strdup(dirpath);
 	if (!path) {
-		fprintf(stderr, "Out of memory.\n");
-		exit(1);
+		perror("Duplicate new directory failed:");
+		goto done;
 	}
 
-	currpath = path;
-
-	if (!getcwd(cwd, MAX_PATH)) {
-		free(path);
-		fprintf(stderr, "Error getting cwd.\n");
-		return -1;
+	if (NULL == realpath(parent, rpar)) {
+		fprintf(stderr, "realpath(%s) failed: %s\n", parent,
+			strerror(errno));
+		goto done;
 	}
+	parlen = strlen(rpar);
 
-	do {
-		pos = index(currpath, '/');
-		if (pos)
-			*pos = 0;
+	for (subdir = path, dirsep = 0; subdir[dirsep]; subdir += dirsep) {
+		dirsep = strcspn(subdir, "/\\");
+		if (!dirsep) {
+			subdir++;
+			continue;
+		}
 
-		/* printf("cp=%s\n", currpath); */
-		mkdir(currpath, mode);
-		ret = chdir(currpath);
+		c = subdir[dirsep];
+		subdir[dirsep] = 0;
+		r = realpath(path, rsub);
+		sublen = strlen(rsub);
+		if (NULL == r) {
+			if(ENOENT != errno) {
+				fprintf(stderr, "realpath(%s) failed: %s\n",
+					path, strerror(errno));
+				goto done;
+			}
+		} else if (sublen < parlen || strncmp(rpar, rsub, parlen)) {
+			fprintf(stderr, "Abort: %s is outside %s\n", dirpath,
+				parent);
+			goto done;
+		}
+		if(-1 == mkdir(path, mode) && EEXIST != errno) {
+			fprintf(stderr, "mkdir(%s): %s\n", path,
+				strerror(errno));
+			goto done;
+		}
+		subdir[dirsep] = c;
+	}
+	ret = 0;
 
-		if (pos)
-			currpath = pos + 1;
-	} while (pos && !ret && strlen(currpath));
-
-	chdir(cwd);
-	free(path);
-
+done:
+	if (path)
+		free(path);
 	return ret;
 }
 

Modified: LinuxBIOSv3/util/lar/lib.h
===================================================================
--- LinuxBIOSv3/util/lar/lib.h	2007-07-12 20:03:02 UTC (rev 452)
+++ LinuxBIOSv3/util/lar/lib.h	2007-07-13 10:40:31 UTC (rev 453)
@@ -41,7 +41,7 @@
 char *get_bootblock(void);
 
 /* prototypes for lib.c functions */
-int mkdirp(const char *dirpath, mode_t mode);
+int mkdirp_below(const char *parent, const char *dirpath, mode_t mode);
 
 int add_files(const char *name);
 int add_file_or_directory(const char *name);





More information about the coreboot mailing list