]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
MRT Dump: Fix bug with longer filename formats
authorPavel Tvrdik <pawel.tvrdik@gmail.com>
Wed, 27 Apr 2016 08:12:26 +0000 (10:12 +0200)
committerPavel Tvrdik <pawel.tvrdik@gmail.com>
Wed, 27 Apr 2016 08:18:45 +0000 (10:18 +0200)
Length of filename format is based on PATH_MAX. Better treating with
filename format buffer size overflow, no segmentation fault.

nest/route.h
nest/rt-table.c

index 0d3a85f8bbf03c345d93ca8c99c66b448b1d73a4..9ea9563377c518b030a0a57fe853b09076f77090 100644 (file)
@@ -628,6 +628,6 @@ struct mrt_table_config *mrt_table_new_config(void);
 struct mrt_table_dump_ctx;
 int is_route_good_for_table_dump(struct mrt_table_dump_ctx *state, rte *e);
 //char *mrt_table_dump_config_get_filename_fmt(struct rtable *rtable);
-void mrt_table_dump_init_file_descriptor(struct mrt_table_dump_ctx *state);
+struct rfile *mrt_table_dump_init_file_descriptor(struct mrt_table_dump_ctx *state);
 
 #endif
index 4420613d8be87042ea52516c2d952b710b9a6764..9550dd3f4b8d293cb9acfa72535b30a63163b9fd 100644 (file)
@@ -2752,10 +2752,13 @@ mrt_table_dump_cmd_step(void *mrt_table_dump_ctx)
     rfree(state->step);
     if (state->config.c.config)
       config_del_obstacle(state->config.c.config);
-    log(L_INFO "MRT dump of table %s was saved into file \"%s\"", state->rtable->name, state->file_path);
-    if (state->config.c.cli)
+    if (state->rfile)
     {
-      cli_printf(state->config.c.cli, 13, "Dump of table %s was saved into file \"%s\"", state->rtable->name, state->file_path);
+      log(L_INFO "MRT dump of table %s was saved into file \"%s\"", state->rtable->name, state->file_path);
+      if (state->config.c.cli)
+      {
+        cli_printf(state->config.c.cli, 13, "Dump of table %s was saved into file \"%s\"", state->rtable->name, state->file_path);
+      }
     }
     rt_unlock_table(state->rtable);
     mb_free(state->file_path);
@@ -2783,10 +2786,12 @@ mrt_table_dump_init(struct mrt_table_dump_ctx *state)
 
   state->state = MRT_STATE_RUNNING;
   state->rib_sequence_number = 0;
-  mrt_table_dump_init_file_descriptor(state);
   mrt_rib_table_alloc(&state->rib_table);
 
-  bgp_mrt_peer_index_table_dump(state);
+  if (mrt_table_dump_init_file_descriptor(state))
+    bgp_mrt_peer_index_table_dump(state);
+  else
+    state->state = MRT_STATE_COMPLETED;
 }
 
 struct mrt_table_dump_ctx *
@@ -2887,7 +2892,7 @@ mrt_table_dump_get_realpath(const char *filename)
   return path;
 }
 
-void
+struct rfile *
 mrt_table_dump_init_file_descriptor(struct mrt_table_dump_ctx *state)
 {
   char *tablename = state->config.table_cf->name;
@@ -2895,12 +2900,15 @@ mrt_table_dump_init_file_descriptor(struct mrt_table_dump_ctx *state)
 
   if (filename_fmt)
   {
-    struct timeformat timestamp_fmt = {
-       .fmt1 = filename_fmt,
-    };
+    char filename[BIRD_PATH_MAX];
+    struct tm *tm = localtime(&now_real);
+    if (!strftime(filename, sizeof(filename), filename_fmt, tm))
+    {
+      log(L_ERR "Invalid filename format \"%s\"", filename_fmt);
+      mb_free(filename_fmt);
+      return NULL;
+    }
 
-    char filename[TM_DATETIME_BUFFER_SIZE];
-    tm_format_datetime(filename, &timestamp_fmt, now);
     state->rfile = tracked_fopen(rt_table_pool, filename, "a");
 
     const char *filename_fullpath = mrt_table_dump_get_realpath(filename);
@@ -2933,6 +2941,7 @@ mrt_table_dump_init_file_descriptor(struct mrt_table_dump_ctx *state)
       cli_msg(13, "Parsing filename filename_fmt \"%s\" for table %s failed", mrt_table_dump_config_get_filename_fmt(state), tablename);
     }
   }
+  return state->rfile;
 }
 
 static void