mirror of
https://github.com/curl/curl.git
synced 2024-11-27 05:50:21 +08:00
tool_dirhie: Allow directory traversal during creation
- When creating a directory hierarchy do not error when mkdir fails due
to error EACCESS (13) "access denied".
Some file systems allow for directory traversal; in this case that it
should be possible to create child directories when permission to the
parent directory is restricted.
This is a regression caused by me in f16bed0
(precedes curl-7_61_1).
Basically I had assumed that if a directory already existed it would
fail only with error EEXIST, and not error EACCES. The latter may
happen if the directory exists but has certain restricted permissions.
Reported-by: mbeifuss@users.noreply.github.com
Fixes https://github.com/curl/curl/issues/4796
Closes https://github.com/curl/curl/pull/4797
This commit is contained in:
parent
446665606c
commit
4027bd72d9
@ -125,6 +125,7 @@ CURLcode create_dir_hierarchy(const char *outfile, FILE *errors)
|
||||
tempdir = strtok(outdup, PATH_DELIMITERS);
|
||||
|
||||
while(tempdir != NULL) {
|
||||
bool skip = false;
|
||||
tempdir2 = strtok(NULL, PATH_DELIMITERS);
|
||||
/* since strtok returns a token for the last word even
|
||||
if not ending with DIR_CHAR, we need to prune it */
|
||||
@ -133,13 +134,27 @@ CURLcode create_dir_hierarchy(const char *outfile, FILE *errors)
|
||||
if(dlen)
|
||||
msnprintf(&dirbuildup[dlen], outlen - dlen, "%s%s", DIR_CHAR, tempdir);
|
||||
else {
|
||||
if(outdup == tempdir)
|
||||
if(outdup == tempdir) {
|
||||
#if defined(MSDOS) || defined(WIN32)
|
||||
/* Skip creating a drive's current directory.
|
||||
It may seem as though that would harmlessly fail but it could be
|
||||
a corner case if X: did not exist, since we would be creating it
|
||||
erroneously.
|
||||
eg if outfile is X:\foo\bar\filename then don't mkdir X:
|
||||
This logic takes into account unsupported drives !:, 1:, etc. */
|
||||
char *p = strchr(tempdir, ':');
|
||||
if(p && !p[1])
|
||||
skip = true;
|
||||
#endif
|
||||
/* the output string doesn't start with a separator */
|
||||
strcpy(dirbuildup, tempdir);
|
||||
}
|
||||
else
|
||||
msnprintf(dirbuildup, outlen, "%s%s", DIR_CHAR, tempdir);
|
||||
}
|
||||
if((-1 == mkdir(dirbuildup, (mode_t)0000750)) && (errno != EEXIST)) {
|
||||
/* Create directory. Ignore access denied error to allow traversal. */
|
||||
if(!skip && (-1 == mkdir(dirbuildup, (mode_t)0000750)) &&
|
||||
(errno != EACCES) && (errno != EEXIST)) {
|
||||
show_dir_errno(errors, dirbuildup);
|
||||
result = CURLE_WRITE_ERROR;
|
||||
break; /* get out of loop */
|
||||
|
Loading…
Reference in New Issue
Block a user