refcnt_init starts counting at 1, while the existing code starts at 0. Do the crashes stop because we never fully release all the references and never free it now?
On Sat, 6 Feb 2021, 10:55 Alexander Bluhm, <alexander.bl...@gmx.net> wrote: > Hi, > > When I replace the ++ and -- of ifg_refcnt with an atomic operation, > it fixes this syzkaller panic. > > > https://syzkaller.appspot.com/bug?id=54e16dc5bce6929e14b42e2f1379f1c18f62be43 > > Without the fix "syz-execprog -repeat=0 -procs=8 repro-pfi.syz" > crashes my vmm in a few seconds. With the diff I cannot reproduce > for several minutes. > > ok? > > bluhm > > Index: net/if.c > =================================================================== > RCS file: /cvs/src/sys/net/if.c,v > retrieving revision 1.626 > diff -u -p -r1.626 if.c > --- net/if.c 1 Feb 2021 07:43:33 -0000 1.626 > +++ net/if.c 6 Feb 2021 00:37:50 -0000 > @@ -2601,7 +2601,7 @@ if_creategroup(const char *groupname) > return (NULL); > > strlcpy(ifg->ifg_group, groupname, sizeof(ifg->ifg_group)); > - ifg->ifg_refcnt = 0; > + refcnt_init(&ifg->ifg_refcnt); > ifg->ifg_carp_demoted = 0; > TAILQ_INIT(&ifg->ifg_members); > #if NPF > 0 > @@ -2648,7 +2648,7 @@ if_addgroup(struct ifnet *ifp, const cha > return (ENOMEM); > } > > - ifg->ifg_refcnt++; > + refcnt_take(&ifg->ifg_refcnt); > ifgl->ifgl_group = ifg; > ifgm->ifgm_ifp = ifp; > > @@ -2692,7 +2692,7 @@ if_delgroup(struct ifnet *ifp, const cha > pfi_group_change(groupname); > #endif > > - if (--ifgl->ifgl_group->ifg_refcnt == 0) { > + if (refcnt_rele(&ifgl->ifgl_group->ifg_refcnt)) { > TAILQ_REMOVE(&ifg_head, ifgl->ifgl_group, ifg_next); > #if NPF > 0 > pfi_detach_ifgroup(ifgl->ifgl_group); > Index: net/if_var.h > =================================================================== > RCS file: /cvs/src/sys/net/if_var.h,v > retrieving revision 1.112 > diff -u -p -r1.112 if_var.h > --- net/if_var.h 29 Jul 2020 12:09:31 -0000 1.112 > +++ net/if_var.h 6 Feb 2021 00:38:23 -0000 > @@ -263,7 +263,7 @@ struct ifmaddr { > > struct ifg_group { > char ifg_group[IFNAMSIZ]; > - u_int ifg_refcnt; > + struct refcnt ifg_refcnt; > caddr_t ifg_pf_kif; > int ifg_carp_demoted; > TAILQ_HEAD(, ifg_member) ifg_members; > Index: netinet/ip_carp.c > =================================================================== > RCS file: /cvs/src/sys/netinet/ip_carp.c,v > retrieving revision 1.351 > diff -u -p -r1.351 ip_carp.c > --- netinet/ip_carp.c 21 Jan 2021 13:18:07 -0000 1.351 > +++ netinet/ip_carp.c 6 Feb 2021 00:39:14 -0000 > @@ -789,7 +789,7 @@ carpattach(int n) > struct ifg_group *ifg; > > if ((ifg = if_creategroup("carp")) != NULL) > - ifg->ifg_refcnt++; /* keep around even if empty */ > + refcnt_take(&ifg->ifg_refcnt); /* keep around even if > empty */ > if_clone_attach(&carp_cloner); > carpcounters = counters_alloc(carps_ncounters); > } > >