On Mon, Dec 08, 2025 at 10:04:21PM +0300, Alexander Mukhin wrote:
> On Thu, Dec 04, 2025 at 04:51:55PM +0300, Alexander Mukhin wrote:
> > >Synopsis:  ospfd and ripd dump core on exit
> > >Category:  user
> > >Environment:
> >     System      : OpenBSD 7.8
> >     Details     : OpenBSD 7.8 (GENERIC) #54: Sun Oct 12 12:45:58 MDT 2025
> >                      
> > [email protected]:/usr/src/sys/arch/amd64/compile/GENERIC
> > 
> >     Architecture: OpenBSD.amd64
> >     Machine     : amd64
> > >Description:
> >     ospfd and ripd dump core on exit when static redistribution is enabled
> > >How-To-Repeat:
> >     # cat ospfd.conf
> >     redistribute static
> >     area 0.0.0.0 {
> >             interface vio1
> >     }
> >     # route add ...
> >     # ospfd -d -v -f ospfd.conf
> >     ...
> >     ^C
> >     ...
> >     Segmentation fault (core dumped)
> > 
> >     # cat ripd.conf
> >     redistribute static
> >     interface vio1
> >     # route add ...
> >     # ripd -d -v -f ripd.conf
> >     ...
> >     ^C
> >     ...
> >     Segmentation fault (core dumped)
> > 
> > >Fix:
> >     The reason is the same in both cases - sending imsgs through
> >     closed pipes. Calling kr_shutdown() before closing pipes helps.
> >     The proper fix is probably something like Claudio Jeker did
> >     for ldpd.
> 
> Patches:
> 
> --- ospfd.c
> +++ ospfd.c
> @@ -313,6 +313,8 @@
>       int                      status;
>       struct redistribute     *r;
>  
> +     kr_shutdown();
> +
>       /* close pipes */
>       imsgbuf_clear(&iev_ospfe->ibuf);
>       close(iev_ospfe->ibuf.fd);
> @@ -324,7 +326,6 @@
>               SIMPLEQ_REMOVE_HEAD(&ospfd_conf->redist_list, entry);
>               free(r);
>       }
> -     kr_shutdown();
>       carp_demote_shutdown();
>  
>       log_debug("waiting for children to terminate");
> 
> 
> --- ripd.c
> +++ ripd.c
> @@ -271,6 +271,8 @@
>       pid_t            pid;
>       int              status;
>  
> +     kr_shutdown();
> +
>       /* close pipes */
>       imsgbuf_clear(&iev_ripe->ibuf);
>       close(iev_ripe->ibuf.fd);
> @@ -281,8 +283,6 @@
>               LIST_REMOVE(i, entry);
>               if_del(i);
>       }
> -
> -     kr_shutdown();
>  
>       log_debug("waiting for children to terminate");
>       do {
> 

Thanks Alexander for your patch.

I would suggest to the following diff.  So, the code is more like the
ospfe_shutdown() in ospfe.c.  Closing the imsg buffer after disabling
the timers, also prevents a race here, because the timer functions also
dealing with imsg stuff.  And the problem is also solved for ospf6d(8).

ok?

Index: usr.sbin/ospf6d/ospf6d.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospf6d/ospf6d.c,v
diff -u -p -r1.61 ospf6d.c
--- usr.sbin/ospf6d/ospf6d.c    21 Nov 2024 13:38:14 -0000      1.61
+++ usr.sbin/ospf6d/ospf6d.c    5 May 2026 12:21:52 -0000
@@ -301,12 +301,6 @@ ospfd_shutdown(void)
        pid_t   pid;
        int     status;
 
-       /* close pipes */
-       imsgbuf_clear(&iev_ospfe->ibuf);
-       close(iev_ospfe->ibuf.fd);
-       imsgbuf_clear(&iev_rde->ibuf);
-       close(iev_rde->ibuf.fd);
-
        control_cleanup();
        kr_shutdown();
        carp_demote_shutdown();
@@ -322,6 +316,12 @@ ospfd_shutdown(void)
                            (pid == rde_pid) ? "route decision engine" :
                            "ospf engine", WTERMSIG(status));
        } while (pid != -1 || (pid == -1 && errno == EINTR));
+
+       /* close pipes */
+       imsgbuf_clear(&iev_ospfe->ibuf);
+       close(iev_ospfe->ibuf.fd);
+       imsgbuf_clear(&iev_rde->ibuf);
+       close(iev_rde->ibuf.fd);
 
        free(iev_ospfe);
        free(iev_rde);
Index: usr.sbin/ospfd/ospfd.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/ospfd.c,v
diff -u -p -r1.124 ospfd.c
--- usr.sbin/ospfd/ospfd.c      21 Nov 2024 13:38:14 -0000      1.124
+++ usr.sbin/ospfd/ospfd.c      5 May 2026 12:21:52 -0000
@@ -313,12 +313,6 @@ ospfd_shutdown(void)
        int                      status;
        struct redistribute     *r;
 
-       /* close pipes */
-       imsgbuf_clear(&iev_ospfe->ibuf);
-       close(iev_ospfe->ibuf.fd);
-       imsgbuf_clear(&iev_rde->ibuf);
-       close(iev_rde->ibuf.fd);
-
        control_cleanup();
        while ((r = SIMPLEQ_FIRST(&ospfd_conf->redist_list)) != NULL) {
                SIMPLEQ_REMOVE_HEAD(&ospfd_conf->redist_list, entry);
@@ -338,6 +332,12 @@ ospfd_shutdown(void)
                            (pid == rde_pid) ? "route decision engine" :
                            "ospf engine", WTERMSIG(status));
        } while (pid != -1 || (pid == -1 && errno == EINTR));
+
+       /* close pipes */
+       imsgbuf_clear(&iev_ospfe->ibuf);
+       close(iev_ospfe->ibuf.fd);
+       imsgbuf_clear(&iev_rde->ibuf);
+       close(iev_rde->ibuf.fd);
 
        free(iev_ospfe);
        free(iev_rde);

Reply via email to