]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
MRT: Fix crash when protocol mrtdump configured without a specified file
authorMaria Matejka <mq@ucw.cz>
Tue, 25 Nov 2025 17:22:26 +0000 (18:22 +0100)
committerMaria Matejka <mq@ucw.cz>
Tue, 25 Nov 2025 17:26:25 +0000 (18:26 +0100)
If somebody configured mrtdump option in the protocol block and had no
mrtdump file configured on toplevel, BIRD 3 would crash on first MRT
message to be written after that.

Fixed by passing the rfile structure through up to the actual place
where mrt_dump_message() checks whether anything is open. Theoretically
there could be a smaller fix involving just adding null-checks to
mrt_dump_bgp_message() and mrt_dump_bgp_state_change(), but this is more
future-proof.

Reported-By: Káťa Kubecová
Fixes: #243
proto/mrt/mrt.c
proto/mrt/mrt.h

index 6544aef493453dacb7a6d705eb8567512a88f19c..2c5f7795d2f4a36c1234d947b287513eca08d986 100644 (file)
@@ -182,7 +182,7 @@ mrt_init_message(buffer *b, u16 type, u16 subtype)
 }
 
 static void
-mrt_dump_message(buffer *b, int fd)
+mrt_dump_message(buffer *b, struct rfile *rf)
 {
   uint len = mrt_buffer_pos(b);
 
@@ -190,10 +190,10 @@ mrt_dump_message(buffer *b, int fd)
   ASSERT(len >= MRT_HDR_LENGTH);
   put_u32(b->start + 8, len - MRT_HDR_LENGTH);
 
-  if (fd < 0)
+  if (!rf)
     return;
 
-  if (write(fd, b->start, len) < 0)
+  if (write(rf_fileno(rf), b->start, len) < 0)
     log(L_ERR "Write to MRT file failed: %m"); /* TODO: name of file */
 }
 
@@ -251,7 +251,6 @@ mrt_open_file(struct mrt_table_dump_state *s)
     return 0;
   }
 
-  s->fd = rf_fileno(s->file);
   s->time_offset = now_real - now;
 
   return 1;
@@ -262,7 +261,6 @@ mrt_close_file(struct mrt_table_dump_state *s)
 {
   rfree(s->file);
   s->file = NULL;
-  s->fd = -1;
 }
 
 
@@ -359,7 +357,7 @@ mrt_peer_table_dump(struct mrt_table_dump_state *s)
   /* Fix Peer Count */
   put_u16(s->buf.start + s->peer_count_offset, s->peer_count);
 
-  mrt_dump_message(&s->buf, s->fd);
+  mrt_dump_message(&s->buf, s->file);
 }
 
 static void
@@ -531,7 +529,7 @@ mrt_rib_table_dump(struct mrt_table_dump_state *s, const struct rt_export_feed *
     return;
 
   s->seqnum++;
-  mrt_dump_message(&s->buf, s->fd);
+  mrt_dump_message(&s->buf, s->file);
 }
 
 /*
@@ -609,8 +607,6 @@ mrt_table_dump_init(pool *pp, const char *name)
 
   OBSREF_SET(s->config, OBSREF_GET(config));
 
-  s->fd = -1;
-
   return s;
 }
 
@@ -870,7 +866,7 @@ mrt_dump_bgp_message(struct mrt_bgp_data *d, pool *p)
   mrt_init_message(b, MRT_BGP4MP, subtypes[d->as4 + 4*d->add_path]);
   mrt_bgp_header(b, d);
   mrt_put_data(b, d->message, d->msg_len);
-  mrt_dump_message(b, rf_fileno(OBSREF_GET(config)->mrtdump_file));
+  mrt_dump_message(b, OBSREF_GET(config)->mrtdump_file);
   mrt_buffer_free(b);
 }
 
@@ -891,7 +887,7 @@ mrt_dump_bgp_state_change(struct mrt_bgp_data *d, pool *p)
   mrt_bgp_header(b, d);
   mrt_put_u16(b, states[d->old_state]);
   mrt_put_u16(b, states[d->new_state]);
-  mrt_dump_message(b, rf_fileno(OBSREF_GET(config)->mrtdump_file));
+  mrt_dump_message(b, OBSREF_GET(config)->mrtdump_file);
   mrt_buffer_free(b);
 }
 
index b256ca9e9737832ed55db8c30eef2c33b6076c6d..eaadbdcdc547332c23757fb62011c7a66302ca2a 100644 (file)
@@ -92,8 +92,7 @@ struct mrt_table_dump_state {
   u16 entry_count;                     /* Number of RIB Entries */
   u32 entry_count_offset;              /* Buffer offset to store entry_count later */
 
-  struct rfile *file;                  /* tracking for mrt table dump file */
-  int fd;
+  struct rfile *file;                  /* Table dump file */
 
   event *event;                                /* defer event */
   event_list *target;                  /* defer target */