summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2016-02-25 13:31:28 -0500
committerNick Mathewson <nickm@torproject.org>2016-02-25 13:34:12 -0500
commit7255b1121d8cdba4427c86a63bada1c07edc45be (patch)
tree144ea7b8ddb5863362a171a78c652192432ad4c2 /src/common
parent1318c1611fed301f44d69a2d6e4f012efd94c9cc (diff)
downloadtor-7255b1121d8cdba4427c86a63bada1c07edc45be.tar.gz
tor-7255b1121d8cdba4427c86a63bada1c07edc45be.zip
Fix check_private_dir() to work on Windows again.
On windows, you cannot open() a directory. So for Windows we should just take our previous stat-based approach. Closes bug 18392; bug not in any released Tor.
Diffstat (limited to 'src/common')
-rw-r--r--src/common/util.c49
1 files changed, 38 insertions, 11 deletions
diff --git a/src/common/util.c b/src/common/util.c
index 488f1b6ca8..5713235085 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -2059,15 +2059,14 @@ check_private_dir(const char *dirname, cpd_check_t check,
int fd;
int r;
struct stat st;
- //char *f;
+
+ tor_assert(dirname);
+
#ifndef _WIN32
unsigned unwanted_bits = 0;
const struct passwd *pw = NULL;
uid_t running_uid;
gid_t running_gid;
-#else
- (void)effective_user;
-#endif
/*
* Goal is to harden the implementation by removing any
@@ -2078,7 +2077,6 @@ check_private_dir(const char *dirname, cpd_check_t check,
* Several suggestions taken from:
* https://developer.apple.com/library/mac/documentation/Security/Conceptual/SecureCodingGuide/Articles/RaceConditions.html
*/
- tor_assert(dirname);
/* Open directory.
* O_NOFOLLOW to ensure that it does not follow symbolic links */
@@ -2099,15 +2097,11 @@ check_private_dir(const char *dirname, cpd_check_t check,
/* Should we create the directory? */
if (check & CPD_CREATE) {
log_info(LD_GENERAL, "Creating directory %s", dirname);
-#if defined (_WIN32)
- r = mkdir(dirname);
-#else
if (check & CPD_GROUP_READ) {
r = mkdir(dirname, 0750);
} else {
r = mkdir(dirname, 0700);
}
-#endif
/* check for mkdir() error */
if (r) {
@@ -2153,7 +2147,6 @@ check_private_dir(const char *dirname, cpd_check_t check,
return -1;
}
-#ifndef _WIN32
if (effective_user) {
/* Look up the user and group information.
* If we have a problem, bail out. */
@@ -2234,8 +2227,42 @@ check_private_dir(const char *dirname, cpd_check_t check,
return 0;
}
}
-#endif
close(fd);
+#else
+ /* Win32 case: we can't open() a directory. */
+ (void)effective_user;
+
+ char *f = tor_strdup(dirname);
+ clean_name_for_stat(f);
+ log_debug(LD_FS, "stat()ing %s", f);
+ r = stat(sandbox_intern_string(f), &st);
+ tor_free(f);
+ if (r) {
+ if (errno != ENOENT) {
+ log_warn(LD_FS, "Directory %s cannot be read: %s", dirname,
+ strerror(errno));
+ return -1;
+ }
+ if (check & CPD_CREATE) {
+ log_info(LD_GENERAL, "Creating directory %s", dirname);
+ r = mkdir(dirname);
+ if (r) {
+ log_warn(LD_FS, "Error creating directory %s: %s", dirname,
+ strerror(errno));
+ return -1;
+ }
+ } else if (!(check & CPD_CHECK)) {
+ log_warn(LD_FS, "Directory %s does not exist.", dirname);
+ return -1;
+ }
+ return 0;
+ }
+ if (!(st.st_mode & S_IFDIR)) {
+ log_warn(LD_FS, "%s is not a directory", dirname);
+ return -1;
+ }
+
+#endif
return 0;
}