From: Zbynek Jun Date: Mon, 21 Sep 2015 11:27:39 +0000 (+0200) Subject: Fix recursive directory creation in rrdcached on FREEBSD X-Git-Tag: v1.6.0~25^2~10^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F671%2Fhead;p=thirdparty%2Frrdtool-1.x.git Fix recursive directory creation in rrdcached on FREEBSD --- diff --git a/src/rrd_daemon.c b/src/rrd_daemon.c index 4a2fb1c5..f4fe4811 100644 --- a/src/rrd_daemon.c +++ b/src/rrd_daemon.c @@ -475,7 +475,7 @@ static int open_pidfile(char *action, int oflag) /* {{{ */ return -1; } - dir = dirname(file_copy); + dir = strdup(dirname(file_copy)); if (rrd_mkdir_p(dir, 0777) != 0) { fprintf(stderr, "Failed to create pidfile directory '%s': %s\n", @@ -2250,7 +2250,7 @@ static int handle_request_create (HANDLER_PROTO) /* {{{ */ RRDD_LOG(LOG_INFO, "rrdcreate request for %s",file); pthread_mutex_lock(&rrdfilecreate_lock); - dir = dirname(file_copy); + dir = strdup(dirname(file_copy)); dir2 = realpath(dir, NULL); if (dir2 == NULL && errno == ENOENT) { if (!config_allow_recursive_mkdir) { @@ -3269,7 +3269,7 @@ static int open_listen_socket_unix (const listen_socket_t *sock) /* {{{ */ return (-1); } - dir = dirname(path_copy); + dir = strdup(dirname(path_copy)); if (rrd_mkdir_p(dir, 0777) != 0) { fprintf(stderr, "Failed to create socket directory '%s': %s\n", diff --git a/src/rrd_utils.c b/src/rrd_utils.c index 0ff25f1f..772afded 100644 --- a/src/rrd_utils.c +++ b/src/rrd_utils.c @@ -148,19 +148,25 @@ void rrd_free_ptrs(void ***src, size_t *cnt) /* recursively create the directory named by 'pathname' * (similar to "mkdir -p" on the command line) */ -int rrd_mkdir_p(const char *pathname, mode_t mode) +int rrd_mkdir_p(const char *pathname_unsafe, mode_t mode) { struct stat sb; + char *pathname; char *pathname_copy; char *base_dir; - if ((NULL == pathname) || ('\0' == *pathname)) { + if ((NULL == pathname_unsafe) || ('\0' == *pathname_unsafe)) { errno = EINVAL; return -1; } + /* dirname returns repeatedly same pointer - make pathname safe (bsd)*/ + if (NULL == (pathname = strdup(pathname_unsafe))) + return -1; + if (0 == stat(pathname, &sb)) { + free(pathname); if (! S_ISDIR(sb.st_mode)) { errno = ENOTDIR; return -1; @@ -169,21 +175,27 @@ int rrd_mkdir_p(const char *pathname, mode_t mode) } /* keep errno as set by stat() */ - if (ENOENT != errno) + if (ENOENT != errno) { + free(pathname); return -1; + } /* dirname might modify its first argument */ - if (NULL == (pathname_copy = strdup(pathname))) + if (NULL == (pathname_copy = strdup(pathname))) { + free(pathname); return -1; + } #ifndef _MSC_VER /* the data pointedd too by dirname might change too (bsd) */ if (NULL == (base_dir = strdup(dirname(pathname_copy)))) { + free(pathname); free(pathname_copy); return -1; } #else if (NULL == (base_dir = strdup(pathname_copy))) { + free(pathname); free(pathname_copy); return -1; } @@ -193,6 +205,7 @@ int rrd_mkdir_p(const char *pathname, mode_t mode) if (0 != rrd_mkdir_p(base_dir, mode)) { int orig_errno = errno; + free(pathname); free(pathname_copy); free(base_dir); errno = orig_errno; @@ -204,12 +217,17 @@ int rrd_mkdir_p(const char *pathname, mode_t mode) /* keep errno as set by mkdir() */ #ifdef _MSC_VER - if (0 != mkdir(pathname)) + if (0 != mkdir(pathname)) { + free(pathname); return -1; + } #else - if (0 != mkdir(pathname, mode)) + if (0 != mkdir(pathname, mode)) { + free(pathname); return -1; + } #endif + free(pathname); return 0; } /* rrd_mkdir_p */