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) {
|
if (pos) {
|
||||||
pos[1] = 0;
|
pos[1] = 0;
|
||||||
/* printf("Pathname %s\n",pathname); */
|
/* printf("Pathname %s\n",pathname); */
|
||||||
mkdirp(pathname, 0755);
|
mkdirp_below(".", pathname, 0755);
|
||||||
}
|
}
|
||||||
free(pathname);
|
free(pathname);
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
@ -33,42 +34,82 @@
|
||||||
|
|
||||||
static struct file *files = NULL;
|
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;
|
int ret = -1;
|
||||||
char cwd[MAX_PATH];
|
size_t dirsep, parlen, sublen;
|
||||||
int ret = 0;
|
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);
|
path = strdup(dirpath);
|
||||||
if (!path) {
|
if (!path) {
|
||||||
fprintf(stderr, "Out of memory.\n");
|
perror("Duplicate new directory failed:");
|
||||||
exit(1);
|
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);
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ long get_larsize(void);
|
||||||
char *get_bootblock(void);
|
char *get_bootblock(void);
|
||||||
|
|
||||||
/* prototypes for lib.c functions */
|
/* 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_files(const char *name);
|
||||||
int add_file_or_directory(const char *name);
|
int add_file_or_directory(const char *name);
|
||||||
|
|
Loading…
Add table
Reference in a new issue