Index | Thread | Search

From:
Jan Klemkow <jan@openbsd.org>
Subject:
Fix: ospf{,6}d shutdown crash
To:
tech@openbsd.org
Date:
Tue, 22 Jul 2025 11:22:50 +0200

Download raw body.

Thread
  • Jan Klemkow:

    Fix: ospf{,6}d shutdown crash

Hi,

both ospfd's closing there imsg channels to early.  While removing all
areas they using the closed channels again.  This causes a SIGSEGV in
libutil.

Core was generated by `ospfd'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x0000043bd032461c in ibufq_push (bufq=0x0, buf=0x43cab357500)
    at /usr/src/lib/libutil/imsg-buffer.c:1037
1037            TAILQ_INSERT_TAIL(&bufq->bufs, buf, entry);
(gdb) bt
#0  0x0000043bd032461c in ibufq_push (bufq=0x0, buf=0x43cab357500)
    at /usr/src/lib/libutil/imsg-buffer.c:1037
#1  ibuf_close (msgbuf=0x0, buf=0x43cab357500) at /usr/src/lib/libutil/imsg-buffer.c:434
#2  0x0000043bd031f57a in imsg_close (imsgbuf=0x43bec21d790, msg=0x43cab357500)
    at /usr/src/lib/libutil/imsg.c:411
#3  imsg_compose (imsgbuf=0x43bec21d790, type=<optimized out>, id=<optimized out>,
    pid=<optimized out>, fd=<optimized out>, data=0x43cc0e28120, datalen=48)
    at /usr/src/lib/libutil/imsg.c:259
#4  0x00000439c60daecf in imsg_compose_event ()
#5  0x00000439c60ddd2e in orig_rtr_lsa ()
#6  0x00000439c60cea8e in if_fsm ()
#7  0x00000439c60dbe36 in ospfe_shutdown ()
#8  0x00000439c60dbce7 in ospfe_sig_handler ()
#9  0x0000043bffd3b248 in event_process_active (base=0x43c5ed1e3b0)
    at /usr/src/lib/libevent/event.c:333
#10 event_base_loop (base=0x43c5ed1e3b0, flags=0) at /usr/src/lib/libevent/event.c:483
#11 0x00000439c60dc2df in ospfe ()
#12 0x00000439c60da622 in main ()

The following diff moves the pipe closing code below to prevent this
error.

ok?

bye,
Jan

Index: usr.sbin/ospf6d/ospfe.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospf6d/ospfe.c,v
diff -u -p -r1.78 ospfe.c
--- usr.sbin/ospf6d/ospfe.c	21 Nov 2024 13:38:14 -0000	1.78
+++ usr.sbin/ospf6d/ospfe.c	22 Jul 2025 09:07:02 -0000
@@ -201,14 +201,6 @@ ospfe_shutdown(void)
 	struct area	*area;
 	struct iface	*iface;
 
-	/* close pipes */
-	imsgbuf_write(&iev_rde->ibuf);
-	imsgbuf_clear(&iev_rde->ibuf);
-	close(iev_rde->ibuf.fd);
-	imsgbuf_write(&iev_main->ibuf);
-	imsgbuf_clear(&iev_main->ibuf);
-	close(iev_main->ibuf.fd);
-
 	/* stop all interfaces and remove all areas */
 	while ((area = LIST_FIRST(&oeconf->area_list)) != NULL) {
 		LIST_FOREACH(iface, &area->iface_list, entry) {
@@ -222,6 +214,14 @@ ospfe_shutdown(void)
 	}
 
 	close(oeconf->ospf_socket);
+
+	/* close pipes */
+	imsgbuf_write(&iev_rde->ibuf);
+	imsgbuf_clear(&iev_rde->ibuf);
+	close(iev_rde->ibuf.fd);
+	imsgbuf_write(&iev_main->ibuf);
+	imsgbuf_clear(&iev_main->ibuf);
+	close(iev_main->ibuf.fd);
 
 	/* clean up */
 	free(iev_rde);
Index: usr.sbin/ospfd/ospfe.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/ospfe.c,v
diff -u -p -r1.120 ospfe.c
--- usr.sbin/ospfd/ospfe.c	21 Nov 2024 13:38:14 -0000	1.120
+++ usr.sbin/ospfd/ospfe.c	22 Jul 2025 09:05:51 -0000
@@ -212,14 +212,6 @@ ospfe_shutdown(void)
 	struct area	*area;
 	struct iface	*iface;
 
-	/* close pipes */
-	imsgbuf_write(&iev_rde->ibuf);
-	imsgbuf_clear(&iev_rde->ibuf);
-	close(iev_rde->ibuf.fd);
-	imsgbuf_write(&iev_main->ibuf);
-	imsgbuf_clear(&iev_main->ibuf);
-	close(iev_main->ibuf.fd);
-
 	/* stop all interfaces and remove all areas */
 	while ((area = LIST_FIRST(&oeconf->area_list)) != NULL) {
 		LIST_FOREACH(iface, &area->iface_list, entry) {
@@ -234,6 +226,14 @@ ospfe_shutdown(void)
 
 	nbr_del(nbr_find_peerid(NBR_IDSELF));
 	close(oeconf->ospf_socket);
+
+	/* close pipes */
+	imsgbuf_write(&iev_rde->ibuf);
+	imsgbuf_clear(&iev_rde->ibuf);
+	close(iev_rde->ibuf.fd);
+	imsgbuf_write(&iev_main->ibuf);
+	imsgbuf_clear(&iev_main->ibuf);
+	close(iev_main->ibuf.fd);
 
 	/* clean up */
 	free(iev_rde);