On Sun, Jun 26, 2022 at 12:02:41PM +0200, Moritz Buhl wrote: > On Tue, May 03, 2022 at 09:31:51PM +0200, Alexander Bluhm wrote: > ... > > The code is too complex to be sure what the reason of the syzkaller > > panic is. Sleep in malloc is correct anyway and may improve the > > situation. > > > > Functions with argument values 0 or 1 are hard to read. It would > > be much nicer to pass M_WAITOK or M_NOWAIT. And the variable name > > "intr" does not make sense anymore. pf does not run in interrupt > > context. Call it "mflags" like in pfi_kif_alloc(). Or "wait" like > > in other functions. > > > > Could you cleanup that also? > > I renamed the intr parameter for pfr_create_ktable and pfr_attach_table > and passed it further up the call stack. > In pf_addr_setup I noticed that pf_tbladdr_setup also used to set intr. > I changed it to wait for both, pfi_dynaddr_setup and pf_tbladdr_setup. > > Now it should be a little easier to notice sleeping points in pf_ioctl.c. > > OK?
OK bluhm@ > Index: sys/net/pf.c > =================================================================== > RCS file: /cvs/src/sys/net/pf.c,v > retrieving revision 1.1133 > diff -u -p -r1.1133 pf.c > --- sys/net/pf.c 13 Jun 2022 12:48:00 -0000 1.1133 > +++ sys/net/pf.c 26 Jun 2022 09:21:21 -0000 > @@ -1585,11 +1585,11 @@ pf_purge_expired_states(u_int32_t maxche > } > > int > -pf_tbladdr_setup(struct pf_ruleset *rs, struct pf_addr_wrap *aw) > +pf_tbladdr_setup(struct pf_ruleset *rs, struct pf_addr_wrap *aw, int wait) > { > if (aw->type != PF_ADDR_TABLE) > return (0); > - if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname, 1)) == NULL) > + if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname, wait)) == NULL) > return (1); > return (0); > } > Index: sys/net/pf_if.c > =================================================================== > RCS file: /cvs/src/sys/net/pf_if.c,v > retrieving revision 1.105 > diff -u -p -r1.105 pf_if.c > --- sys/net/pf_if.c 16 May 2022 13:31:19 -0000 1.105 > +++ sys/net/pf_if.c 26 Jun 2022 09:38:43 -0000 > @@ -423,7 +423,7 @@ pfi_match_addr(struct pfi_dynaddr *dyn, > } > > int > -pfi_dynaddr_setup(struct pf_addr_wrap *aw, sa_family_t af) > +pfi_dynaddr_setup(struct pf_addr_wrap *aw, sa_family_t af, int wait) > { > struct pfi_dynaddr *dyn; > char tblname[PF_TABLE_NAME_SIZE]; > @@ -432,8 +432,7 @@ pfi_dynaddr_setup(struct pf_addr_wrap *a > > if (aw->type != PF_ADDR_DYNIFTL) > return (0); > - if ((dyn = pool_get(&pfi_addr_pl, PR_WAITOK | PR_LIMITFAIL | PR_ZERO)) > - == NULL) > + if ((dyn = pool_get(&pfi_addr_pl, wait|PR_LIMITFAIL|PR_ZERO)) == NULL) > return (1); > > if (!strcmp(aw->v.ifname, "self")) > @@ -466,7 +465,7 @@ pfi_dynaddr_setup(struct pf_addr_wrap *a > goto _bad; > } > > - if ((dyn->pfid_kt = pfr_attach_table(ruleset, tblname, 1)) == NULL) { > + if ((dyn->pfid_kt = pfr_attach_table(ruleset, tblname, wait)) == NULL) { > rv = 1; > goto _bad; > } > Index: sys/net/pf_ioctl.c > =================================================================== > RCS file: /cvs/src/sys/net/pf_ioctl.c,v > retrieving revision 1.381 > diff -u -p -r1.381 pf_ioctl.c > --- sys/net/pf_ioctl.c 10 May 2022 23:12:25 -0000 1.381 > +++ sys/net/pf_ioctl.c 26 Jun 2022 09:35:17 -0000 > @@ -891,8 +891,8 @@ int > pf_addr_setup(struct pf_ruleset *ruleset, struct pf_addr_wrap *addr, > sa_family_t af) > { > - if (pfi_dynaddr_setup(addr, af) || > - pf_tbladdr_setup(ruleset, addr) || > + if (pfi_dynaddr_setup(addr, af, PR_WAITOK) || > + pf_tbladdr_setup(ruleset, addr, PR_WAITOK) || > pf_rtlabel_add(addr)) > return (EINVAL); > > @@ -1413,7 +1413,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a > > if (rule->overload_tblname[0]) { > if ((rule->overload_tbl = pfr_attach_table(ruleset, > - rule->overload_tblname, 0)) == NULL) > + rule->overload_tblname, PR_WAITOK)) == NULL) > error = EINVAL; > else > rule->overload_tbl->pfrkt_flags |= > PFR_TFLAG_ACTIVE; > @@ -1636,7 +1636,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t a > > if (newrule->overload_tblname[0]) { > newrule->overload_tbl = pfr_attach_table( > - ruleset, newrule->overload_tblname, 0); > + ruleset, newrule->overload_tblname, > + PR_WAITOK); > if (newrule->overload_tbl == NULL) > error = EINVAL; > else > Index: sys/net/pf_table.c > =================================================================== > RCS file: /cvs/src/sys/net/pf_table.c,v > retrieving revision 1.142 > diff -u -p -r1.142 pf_table.c > --- sys/net/pf_table.c 16 Jun 2022 20:47:26 -0000 1.142 > +++ sys/net/pf_table.c 26 Jun 2022 08:53:20 -0000 > @@ -323,7 +323,7 @@ pfr_add_addrs(struct pfr_table *tbl, str > if (pfr_validate_table(tbl, 0, flags & PFR_FLAG_USERIOCTL)) > return (EINVAL); > tmpkt = pfr_create_ktable(&pfr_nulltable, 0, 0, > - !(flags & PFR_FLAG_USERIOCTL)); > + (flags & PFR_FLAG_USERIOCTL? PR_WAITOK : PR_NOWAIT)); > if (tmpkt == NULL) > return (ENOMEM); > SLIST_INIT(&workq); > @@ -540,7 +540,7 @@ pfr_set_addrs(struct pfr_table *tbl, str > if (kt->pfrkt_flags & PFR_TFLAG_CONST) > return (EPERM); > tmpkt = pfr_create_ktable(&pfr_nulltable, 0, 0, > - !(flags & PFR_FLAG_USERIOCTL)); > + (flags & PFR_FLAG_USERIOCTL? PR_WAITOK : PR_NOWAIT)); > if (tmpkt == NULL) > return (ENOMEM); > pfr_mark_addrs(kt); > @@ -1513,7 +1513,7 @@ pfr_add_tables(struct pfr_table *tbl, in > senderr(EINVAL); > key.pfrkt_flags |= PFR_TFLAG_ACTIVE; > p = pfr_create_ktable(&key.pfrkt_t, tzero, 0, > - !(flags & PFR_FLAG_USERIOCTL)); > + (flags & PFR_FLAG_USERIOCTL? PR_WAITOK : PR_NOWAIT)); > if (p == NULL) > senderr(ENOMEM); > > @@ -1524,7 +1524,7 @@ pfr_add_tables(struct pfr_table *tbl, in > key.pfrkt_flags = 0; > memset(key.pfrkt_anchor, 0, sizeof(key.pfrkt_anchor)); > p->pfrkt_root = pfr_create_ktable(&key.pfrkt_t, 0, 0, > - !(flags & PFR_FLAG_USERIOCTL)); > + (flags & PFR_FLAG_USERIOCTL? PR_WAITOK : PR_NOWAIT)); > if (p->pfrkt_root == NULL) { > pfr_destroy_ktable(p, 0); > senderr(ENOMEM); > @@ -1910,7 +1910,7 @@ pfr_ina_define(struct pfr_table *tbl, st > kt = RB_FIND(pfr_ktablehead, &pfr_ktables, (struct pfr_ktable *)tbl); > if (kt == NULL) { > kt = pfr_create_ktable(tbl, 0, 1, > - !(flags & PFR_FLAG_USERIOCTL)); > + (flags & PFR_FLAG_USERIOCTL? PR_WAITOK : PR_NOWAIT)); > if (kt == NULL) > return (ENOMEM); > SLIST_INSERT_HEAD(&tableq, kt, pfrkt_workq); > @@ -1927,7 +1927,7 @@ pfr_ina_define(struct pfr_table *tbl, st > goto _skip; > } > rt = pfr_create_ktable(&key.pfrkt_t, 0, 1, > - !(flags & PFR_FLAG_USERIOCTL)); > + (flags & PFR_FLAG_USERIOCTL? PR_WAITOK : PR_NOWAIT)); > if (rt == NULL) { > pfr_destroy_ktables(&tableq, 0); > return (ENOMEM); > @@ -1937,7 +1937,8 @@ pfr_ina_define(struct pfr_table *tbl, st > } else if (!(kt->pfrkt_flags & PFR_TFLAG_INACTIVE)) > xadd++; > _skip: > - shadow = pfr_create_ktable(tbl, 0, 0, !(flags & PFR_FLAG_USERIOCTL)); > + shadow = pfr_create_ktable(tbl, 0, 0, > + (flags & PFR_FLAG_USERIOCTL? PR_WAITOK : PR_NOWAIT)); > if (shadow == NULL) { > pfr_destroy_ktables(&tableq, 0); > return (ENOMEM); > @@ -2286,15 +2287,12 @@ pfr_clstats_ktable(struct pfr_ktable *kt > > struct pfr_ktable * > pfr_create_ktable(struct pfr_table *tbl, time_t tzero, int attachruleset, > - int intr) > + int wait) > { > struct pfr_ktable *kt; > struct pf_ruleset *rs; > > - if (intr) > - kt = pool_get(&pfr_ktable_pl, PR_NOWAIT|PR_ZERO|PR_LIMITFAIL); > - else > - kt = pool_get(&pfr_ktable_pl, PR_WAITOK|PR_ZERO|PR_LIMITFAIL); > + kt = pool_get(&pfr_ktable_pl, wait|PR_ZERO|PR_LIMITFAIL); > if (kt == NULL) > return (NULL); > kt->pfrkt_t = *tbl; > @@ -2533,7 +2531,7 @@ pfr_update_stats(struct pfr_ktable *kt, > } > > struct pfr_ktable * > -pfr_attach_table(struct pf_ruleset *rs, char *name, int intr) > +pfr_attach_table(struct pf_ruleset *rs, char *name, int wait) > { > struct pfr_ktable *kt, *rt; > struct pfr_table tbl; > @@ -2545,14 +2543,14 @@ pfr_attach_table(struct pf_ruleset *rs, > strlcpy(tbl.pfrt_anchor, ac->path, sizeof(tbl.pfrt_anchor)); > kt = pfr_lookup_table(&tbl); > if (kt == NULL) { > - kt = pfr_create_ktable(&tbl, gettime(), 1, intr); > + kt = pfr_create_ktable(&tbl, gettime(), 1, wait); > if (kt == NULL) > return (NULL); > if (ac != NULL) { > bzero(tbl.pfrt_anchor, sizeof(tbl.pfrt_anchor)); > rt = pfr_lookup_table(&tbl); > if (rt == NULL) { > - rt = pfr_create_ktable(&tbl, 0, 1, intr); > + rt = pfr_create_ktable(&tbl, 0, 1, wait); > if (rt == NULL) { > pfr_destroy_ktable(kt, 0); > return (NULL); > Index: sys/net/pfvar.h > =================================================================== > RCS file: /cvs/src/sys/net/pfvar.h,v > retrieving revision 1.507 > diff -u -p -r1.507 pfvar.h > --- sys/net/pfvar.h 29 Apr 2022 09:55:43 -0000 1.507 > +++ sys/net/pfvar.h 26 Jun 2022 09:21:07 -0000 > @@ -1709,7 +1709,7 @@ extern struct ifnet *sync_ifp; > extern struct pf_rule pf_default_rule; > > extern int pf_tbladdr_setup(struct pf_ruleset *, > - struct pf_addr_wrap *); > + struct pf_addr_wrap *, int); > extern void pf_tbladdr_remove(struct pf_addr_wrap *); > extern void pf_tbladdr_copyout(struct pf_addr_wrap *); > extern void pf_calc_skip_steps(struct pf_rulequeue *); > @@ -1875,7 +1875,7 @@ void pfi_group_addmember(const char *) > void pfi_group_delmember(const char *); > int pfi_match_addr(struct pfi_dynaddr *, struct pf_addr *, > sa_family_t); > -int pfi_dynaddr_setup(struct pf_addr_wrap *, sa_family_t); > +int pfi_dynaddr_setup(struct pf_addr_wrap *, sa_family_t, int); > void pfi_dynaddr_remove(struct pf_addr_wrap *); > void pfi_dynaddr_copyout(struct pf_addr_wrap *); > void pfi_update_status(const char *, struct pf_status *);