On Fri, Mar 13, 2015 at 01:14:45AM +0000, Stuart Henderson wrote:
> While investigating a problem reported by Sevan Janiyan (where interface
> pppoe0 { passive } didn't get redisted) I ran into this reproducible
> crash.
> 
> - start ospfd with a p2p interface (tried with pppoe and gif here).
> "passive" is required, e.g. interface gif0 { passive }
> 
> - remove above p2p interface from config
> 
> - ospfctl reload
> 
> - *boom*
> 
> Considering the address of tree, it would appear to be a use after free.
> (Hooray for kern.nosuidcoredump=3)
> 
> (gdb) bt
> #0  0x00001e7559e24880 in lsa_tree_RB_FIND (head=0xdfdfdfdfdfdfdff7, 
>     elm=0x7f7ffffe5310) at /usr/src/usr.sbin/ospfd/rde_lsdb.c:39
> #1  0x00001e7559e25e63 in lsa_find_tree (tree=0xdfdfdfdfdfdfdff7, type=1, 
>     ls_id=1224736778, adv_rtr=1224736778)
>     at /usr/src/usr.sbin/ospfd/rde_lsdb.c:526
> #2  0x00001e7559e25da9 in lsa_find (iface=0x1e77c1c00000, type=1 '\001', 
>     ls_id=1224736778, adv_rtr=1224736778)
>     at /usr/src/usr.sbin/ospfd/rde_lsdb.c:505
> #3  0x00001e7559e2021f in rde_dispatch_imsg (fd=8, event=2, 
>     bula=0x1e7814ade000) at /usr/src/usr.sbin/ospfd/rde.c:421
> #4  0x00001e77681e81a8 in event_base_loop (base=0x1e77c1bff400, 
> flags=Variable "flags" is not available.
> )
>     at /usr/src/lib/libevent/event.c:350
> #5  0x00001e7559e1f862 in rde (xconf=0x1e77833ec800, 
>     pipe_parent2rde=0x1e755a2358a8, pipe_ospfe2rde=0x1e755a2358b8, 
>     pipe_parent2ospfe=0x1e755a2358a0) at /usr/src/usr.sbin/ospfd/rde.c:186
> #6  0x00001e7559e1507e in main (argc=0, argv=0x7f7ffffe5b18)
>     at /usr/src/usr.sbin/ospfd/ospfd.c:242
> 

Can you try the following diff. Not sure if it is right but it seems to
solve the crash for me.

-- 
:wq Claudio

Index: ospfd.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/ospfd.c,v
retrieving revision 1.83
diff -u -p -r1.83 ospfd.c
--- ospfd.c     10 Feb 2015 05:24:48 -0000      1.83
+++ ospfd.c     13 Mar 2015 08:13:00 -0000
@@ -821,6 +821,8 @@ merge_interfaces(struct area *a, struct 
                            i->name);
                        if (ospfd_process == PROC_OSPF_ENGINE)
                                if_fsm(i, IF_EVT_DOWN);
+                       else if (ospfd_process == PROC_RDE_ENGINE)
+                               rde_nbr_iface_del(i);
                        LIST_REMOVE(i, entry);
                        if_del(i);
                }
Index: rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/rde.c,v
retrieving revision 1.96
diff -u -p -r1.96 rde.c
--- rde.c       12 Jul 2014 20:16:38 -0000      1.96
+++ rde.c       13 Mar 2015 08:10:42 -0000
@@ -963,6 +963,22 @@ rde_nbr_new(u_int32_t peerid, struct rde
 }
 
 void
+rde_nbr_iface_del(struct iface *iface)
+{
+       struct rde_nbr_head     *head;
+       struct rde_nbr          *nbr, *xnbr;
+       u_int32_t                i;
+
+       for (i = 0; i <= rdenbrtable.hashmask; i++) {
+               head = &rdenbrtable.hashtbl[i];
+               LIST_FOREACH_SAFE(nbr, head, hash, xnbr) {
+                       if (nbr->iface == iface)
+                               rde_nbr_del(nbr);
+               }
+       }
+}
+
+void
 rde_nbr_del(struct rde_nbr *nbr)
 {
        if (nbr == NULL)
Index: rde.h
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/rde.h,v
retrieving revision 1.38
diff -u -p -r1.38 rde.h
--- rde.h       9 May 2011 12:24:41 -0000       1.38
+++ rde.h       13 Mar 2015 08:11:15 -0000
@@ -118,6 +118,7 @@ u_int32_t    rde_router_id(void);
 struct area    *rde_backbone_area(void);
 void            rde_send_change_kroute(struct rt_node *);
 void            rde_send_delete_kroute(struct rt_node *);
+void            rde_nbr_iface_del(struct iface *);
 void            rde_nbr_del(struct rde_nbr *);
 int             rde_nbr_loading(struct area *);
 struct rde_nbr *rde_nbr_self(struct area *);

Reply via email to