[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
rrd-developers@lists.oetiker.ch
https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers

Reply via email to