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);
 }

Reply via email to