From f97bfd7ad349f209389857b4c5c11c00afdddc2f Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Tue, 25 Nov 2025 18:22:26 +0100 Subject: [PATCH] MRT: Fix crash when protocol mrtdump configured without a specified file MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 | 18 +++++++----------- proto/mrt/mrt.h | 3 +-- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/proto/mrt/mrt.c b/proto/mrt/mrt.c index 6544aef49..2c5f7795d 100644 --- a/proto/mrt/mrt.c +++ b/proto/mrt/mrt.c @@ -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); } diff --git a/proto/mrt/mrt.h b/proto/mrt/mrt.h index b256ca9e9..eaadbdcdc 100644 --- a/proto/mrt/mrt.h +++ b/proto/mrt/mrt.h @@ -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 */ -- 2.47.3