mirror of
https://github.com/fail0verflow/switch-coreboot.git
synced 2025-05-04 01:39:18 -04:00
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@stuge.se> Acked-by: Stefan Reinauer <stepan@coresystems.de> git-svn-id: svn://coreboot.org/repository/LinuxBIOSv3@453 f3766cd6-281f-0410-b1cd-43a5c92072e9
This commit is contained in:
parent
7e5b9406af
commit
7f49e38558
3 changed files with 71 additions and 30 deletions
|
@ -119,7 +119,7 @@ int extract_lar(const char *archivename, struct file *files)
|
|||
if (pos) {
|
||||
pos[1] = 0;
|
||||
/* printf("Pathname %s\n",pathname); */
|
||||
mkdirp(pathname, 0755);
|
||||
mkdirp_below(".", pathname, 0755);
|
||||
}
|
||||
free(pathname);
|
||||
|
||||
|
|
|
@ -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 (NULL == realpath(parent, rpar)) {
|
||||
fprintf(stderr, "realpath(%s) failed: %s\n", parent,
|
||||
strerror(errno));
|
||||
goto done;
|
||||
}
|
||||
parlen = strlen(rpar);
|
||||
|
||||
if (!getcwd(cwd, MAX_PATH)) {
|
||||
for (subdir = path, dirsep = 0; subdir[dirsep]; subdir += dirsep) {
|
||||
dirsep = strcspn(subdir, "/\\");
|
||||
if (!dirsep) {
|
||||
subdir++;
|
||||
continue;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
done:
|
||||
if (path)
|
||||
free(path);
|
||||
fprintf(stderr, "Error getting cwd.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
do {
|
||||
pos = index(currpath, '/');
|
||||
if (pos)
|
||||
*pos = 0;
|
||||
|
||||
/* printf("cp=%s\n", currpath); */
|
||||
mkdir(currpath, mode);
|
||||
ret = chdir(currpath);
|
||||
|
||||
if (pos)
|
||||
currpath = pos + 1;
|
||||
} while (pos && !ret && strlen(currpath));
|
||||
|
||||
chdir(cwd);
|
||||
free(path);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ long get_larsize(void);
|
|||
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);
|
||||
|
|
Loading…
Add table
Reference in a new issue