Re: ospfd and ripd dump core on exit

Jan Klemkow <[email protected]> Tue, 5 May 2026 16:04:57 +0200
Newsgroups gmane.os.openbsd.bugs
Message-ID <enf653xge7wrafdtgeyig2dq7x2a77upjgwj3b7nhkzk52fecq@3db3qdnx6op5>
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);