[PATCH 2/3] rrd_daemon.c: modified get_abs_path() to avoid PATH_MAX,
modified journal_new_file() likewise,
modified journal_init() likewise
modified read_options() cases 'b' and 'j' to use realpath(path, NULL)
Index: rrdtool-1.4.8.new/src/rrd_daemon.c
===================================================================
--- rrdtool-1.4.8.new.orig/src/rrd_daemon.c 2013-08-05 18:02:26.000000000 +0200
+++ rrdtool-1.4.8.new/src/rrd_daemon.c 2013-08-05 18:37:37.000000000 +0200
@@ -1078,21 +1078,26 @@
/* when using a base dir, convert relative paths to absolute paths.
* if necessary, modifies the "filename" pointer to point
* to the new path created in "tmp". "tmp" is provided
- * by the caller and sizeof(tmp) must be >= PATH_MAX.
+ * by the called function, see below.
*
+ * FIXME: Check this!
* this allows us to optimize for the expected case (absolute path)
* with a no-op.
*/
-static void get_abs_path(char **filename, char *tmp)
+static void get_abs_path(char **filename)
{
- assert(tmp != NULL);
+ char *tmp = NULL;
+ int len = 0;
assert(filename != NULL && *filename != NULL);
if (config_base_dir == NULL || **filename == '/')
return;
- snprintf(tmp, PATH_MAX, "%s/%s", config_base_dir, *filename);
+ len = strlen(config_base_dir) + 1 + strlen(*filename) + 1;
+ tmp = malloc(len);
+ snprintf(tmp, len, "%s/%s", config_base_dir, *filename);
*filename = tmp;
+ free(tmp);
} /* }}} static int get_abs_path */
static int flush_file (const char *filename) /* {{{ */
@@ -1183,7 +1188,7 @@
static int handle_request_flush (HANDLER_PROTO) /* {{{ */
{
- char *file, file_tmp[PATH_MAX];
+ char *file;
int status;
status = buffer_get_field (&buffer, &buffer_size, &file);
@@ -1197,7 +1202,7 @@
stats_flush_received++;
pthread_mutex_unlock(&stats_lock);
- get_abs_path(&file, file_tmp);
+ get_abs_path(&file);
if (!check_file_access(file, sock)) return 0;
status = flush_file (file);
@@ -1238,14 +1243,14 @@
static int handle_request_pending(HANDLER_PROTO) /* {{{ */
{
int status;
- char *file, file_tmp[PATH_MAX];
+ char *file;
cache_item_t *ci;
status = buffer_get_field(&buffer, &buffer_size, &file);
if (status != 0)
return syntax_error(sock,cmd);
- get_abs_path(&file, file_tmp);
+ get_abs_path(&file);
pthread_mutex_lock(&cache_lock);
ci = g_tree_lookup(cache_tree, file);
@@ -1266,13 +1271,13 @@
{
int status;
gboolean found;
- char *file, file_tmp[PATH_MAX];
+ char *file;
status = buffer_get_field(&buffer, &buffer_size, &file);
if (status != 0)
return syntax_error(sock,cmd);
- get_abs_path(&file, file_tmp);
+ get_abs_path(&file);
if (!check_file_access(file, sock)) return 0;
pthread_mutex_lock(&cache_lock);
@@ -1313,7 +1318,7 @@
static int handle_request_update (HANDLER_PROTO) /* {{{ */
{
- char *file, file_tmp[PATH_MAX];
+ char *file;
int values_num = 0;
int status;
char orig_buf[CMD_MAX];
@@ -1332,7 +1337,7 @@
stats_updates_received++;
pthread_mutex_unlock(&stats_lock);
- get_abs_path(&file, file_tmp);
+ get_abs_path(&file);
if (!check_file_access(file, sock)) return 0;
pthread_mutex_lock (&cache_lock);
@@ -1867,8 +1872,8 @@
static void journal_new_file(void) /* {{{ */
{
struct timeval now;
- int new_fd;
- char new_file[PATH_MAX + 1];
+ int new_fd, len;
+ char *new_file = NULL;
assert(journal_dir != NULL);
assert(journal_cur != NULL);
@@ -1877,7 +1882,9 @@
gettimeofday(&now, NULL);
/* this format assures that the files sort in strcmp() order */
- snprintf(new_file, PATH_MAX, "%s/%s.%010d.%06d",
+ len = strlen(journal_dir) + 1 + strlen(JOURNAL_BASE) + 10 + 6 + 1;
+ new_file = malloc(len);
+ snprintf(new_file, len, "%s/%s.%010d.%06d",
journal_dir, JOURNAL_BASE, (int)now.tv_sec, (int)now.tv_usec);
new_fd = open(new_file, O_WRONLY|O_CREAT|O_APPEND,
@@ -1895,6 +1902,7 @@
/* record the file in the journal set */
rrd_add_strdup(&journal_cur->files, &journal_cur->files_num, new_file);
+ free(new_file);
return;
error:
@@ -1904,6 +1912,7 @@
RRDD_LOG(LOG_CRIT,
"JOURNALING DISABLED: All values will be flushed at shutdown");
+ free(new_file);
close(new_fd);
config_flush_at_shutdown = 1;
@@ -1966,7 +1975,6 @@
journal_set_free(journal_cur);
journal_set_free(journal_old);
- free(journal_dir);
} /* }}} static void journal_done */
@@ -2100,10 +2108,10 @@
static void journal_init(void) /* {{{ */
{
- int had_journal = 0;
+ int had_journal = 0, len = 0;
DIR *dir;
struct dirent *dent;
- char path[PATH_MAX+1];
+ char *path = NULL;
if (journal_dir == NULL) return;
@@ -2122,19 +2130,27 @@
* correct sort order. TODO: remove after first release
*/
{
- char old_path[PATH_MAX+1];
- snprintf(old_path, PATH_MAX, "%s/%s", journal_dir, JOURNAL_BASE ".old" );
- snprintf(path, PATH_MAX, "%s/%s", journal_dir, JOURNAL_BASE ".0000");
+ char *old_path = NULL;
+ if (journal_dir != NULL) {
+ len = strlen(journal_dir) + 1 + strlen(JOURNAL_BASE) + 5 + 1;
+ old_path = malloc(len);
+ path = malloc(len);
+ snprintf(old_path, len, "%s/%s", journal_dir, JOURNAL_BASE ".old" );
+ snprintf(path, len, "%s/%s", journal_dir, JOURNAL_BASE ".0000");
rename(old_path, path);
- snprintf(old_path, PATH_MAX, "%s/%s", journal_dir, JOURNAL_BASE );
- snprintf(path, PATH_MAX, "%s/%s", journal_dir, JOURNAL_BASE ".0001");
+ snprintf(old_path, len, "%s/%s", journal_dir, JOURNAL_BASE );
+ snprintf(path, len, "%s/%s", journal_dir, JOURNAL_BASE ".0001");
rename(old_path, path);
+ free(old_path);
+ }
}
+ /* FIXME: Check all free(path) !! */
dir = opendir(journal_dir);
if (!dir) {
RRDD_LOG(LOG_CRIT, "journal_init: opendir(%s) failed\n", journal_dir);
+ free(path);
return;
}
while ((dent = readdir(dir)) != NULL)
@@ -2143,15 +2159,20 @@
if (strncmp(dent->d_name, JOURNAL_BASE, strlen(JOURNAL_BASE)))
continue;
- snprintf(path, PATH_MAX, "%s/%s", journal_dir, dent->d_name);
+ len = strlen(journal_dir) + 1 + strlen(dent->d_name) + 1;
+ path = realloc(path, len);
+ snprintf(path, len, "%s/%s", journal_dir, dent->d_name);
if (!rrd_add_strdup(&journal_cur->files, &journal_cur->files_num, path))
{
RRDD_LOG(LOG_CRIT, "journal_init: cannot add journal file %s!",
dent->d_name);
+ free(path);
break;
}
+ free(path);
}
+ free(path);
closedir(dir);
qsort(journal_cur->files, journal_cur->files_num,
@@ -2827,14 +2848,14 @@
case 'l':
{
- listen_socket_t *new;
+ listen_socket_t *new;
- new = malloc(sizeof(listen_socket_t));
- if (new == NULL)
- {
- fprintf(stderr, "read_options: malloc failed.\n");
- return(2);
- }
+ new = malloc(sizeof(listen_socket_t));
+ if (new == NULL)
+ {
+ fprintf(stderr, "read_options: malloc failed.\n");
+ return(2);
+ }
memset(new, 0, sizeof(listen_socket_t));
strncpy(new->addr, optarg, sizeof(new->addr)-1);
@@ -3007,7 +3028,7 @@
case 'b':
{
size_t len;
- char base_realpath[PATH_MAX];
+ char *base_realpath = NULL;
if (config_base_dir != NULL)
free (config_base_dir);
@@ -3030,7 +3051,7 @@
* assumptions possible (we don't have to resolve paths
* that start with a "/")
*/
- if (realpath(config_base_dir, base_realpath) == NULL)
+ if ((base_realpath = realpath(config_base_dir, NULL)) == NULL)
{
fprintf (stderr, "Failed to canonicalize the base directory '%s': "
"%s\n", config_base_dir, rrd_strerror(errno));
@@ -3060,15 +3081,17 @@
}
if (strncmp(config_base_dir,
- base_realpath, sizeof(base_realpath)) != 0)
+ base_realpath, len) != 0)
{
fprintf(stderr,
"Base directory (-b) resolved via file system links!\n"
"Please consult rrdcached '-b' documentation!\n"
"Consider specifying the real directory (%s)\n",
base_realpath);
+ free(base_realpath);
return 5;
}
+ free(base_realpath);
}
break;
@@ -3091,20 +3114,7 @@
case 'j':
{
- char journal_dir_actual[PATH_MAX];
- const char *dir;
- if (realpath((const char *)optarg, journal_dir_actual) == NULL)
- {
- fprintf(stderr, "Failed to canonicalize the journal directory '%s': %s\n",
- optarg, rrd_strerror(errno));
- return 7;
- }
- dir = journal_dir = strdup(journal_dir_actual);
- if (dir == NULL) {
- fprintf (stderr, "read_options: strdup failed.\n");
- return (3);
- }
-
+ const char *dir = (const char *)optarg;
status = rrd_mkdir_p(dir, 0777);
if (status != 0)
{
@@ -3112,13 +3122,21 @@
dir, rrd_strerror(errno));
return 6;
}
+ journal_dir = realpath((const char *)dir, NULL);
+ if (! journal_dir) {
+ fprintf(stderr, "Failed to canonicalize journal directory '%s': %s\n",
+ dir, rrd_strerror(errno));
+ return 6;
+ }
- if (access(dir, R_OK|W_OK|X_OK) != 0)
+ if (access(journal_dir, R_OK|W_OK|X_OK) != 0)
{
fprintf(stderr, "Must specify a writable directory with -j! (%s)\n",
errno ? rrd_strerror(errno) : "");
+ free(journal_dir);
return 6;
}
+ free(journal_dir);
}
break;
_______________________________________________
rrd-developers mailing list
[email protected]
https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers