On Tue, Jul 04, 2017 at 05:19:46PM +0200, Alexander Bluhm wrote: > Panic happens during /usr/src/regress/sys/ffs/nfs setup. > > login: panic: free: non-malloced addr 0xd4b81630 type rtable > Stopped at db_enter+0x7: leave > TID PID UID PRFLAGS PFLAGS CPU COMMAND > 382123 44974 0 0x100002 0 1 sh > *424094 92583 0 0 0 0 mountd > db_enter(d09d2ab3,f5820bb8,d0baf53c,f5820bb8,d4aa5600) at db_enter+0x7 > panic(d0baf53c,d4b81630,d0aaab21,d4aa5600,2) at panic+0x71 > free(d4b81630,5,0,d09157dc,d4ad2a9c) at free+0xd5 > vfs_free_addrlist(d5f88954,d4ad15f0,f5820c5c,d0779a59,d4ad2a9c) at > vfs_free_add > rlist+0x45 > vfs_export(d5e58c00,d5f88954,f5820cb0,d4ad15f0,d4a99454) at vfs_export+0x63 > ffs_mount(d5e58c00,f5820e92,cf7cd2fc,f5820e2c,d4a99454) at ffs_mount+0x55d > sys_mount(d4a99454,f5820f54,f5820f7c,0,286) at sys_mount+0x2f0 > syscall() at syscall+0x250 > --- syscall (number -813903004) ---
Replacing free() with rn_freehead() in vfs_free_addrlist() fixes this panic. NFS test passes, doing a full test run now. bluhm Index: kern/vfs_subr.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/kern/vfs_subr.c,v retrieving revision 1.259 diff -u -p -r1.259 vfs_subr.c --- kern/vfs_subr.c 20 Apr 2017 14:13:00 -0000 1.259 +++ kern/vfs_subr.c 4 Jul 2017 16:36:03 -0000 @@ -1405,7 +1405,7 @@ vfs_hang_addrlist(struct mount *mp, stru switch (i) { case AF_INET: if ((rnh = nep->ne_rtable_inet) == NULL) { - if (!rn_inithead((void **)&nep->ne_rtable_inet, + if (!rn_inithead(&nep->ne_rtable_inet, offsetof(struct sockaddr_in, sin_addr))) { error = ENOBUFS; goto out; @@ -1450,7 +1450,7 @@ vfs_free_addrlist(struct netexport *nep) if ((rnh = nep->ne_rtable_inet) != NULL) { rn_walktree(rnh, vfs_free_netcred, rnh); - free(rnh, M_RTABLE, 0); + rn_freehead(rnh); nep->ne_rtable_inet = NULL; } } Index: net/pf_table.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/net/pf_table.c,v retrieving revision 1.126 diff -u -p -r1.126 pf_table.c --- net/pf_table.c 8 May 2017 20:24:03 -0000 1.126 +++ net/pf_table.c 4 Jul 2017 16:30:17 -0000 @@ -2010,9 +2010,9 @@ pfr_create_ktable(struct pfr_table *tbl, rs->tables++; } - if (!rn_inithead((void **)&kt->pfrkt_ip4, + if (!rn_inithead(&kt->pfrkt_ip4, offsetof(struct sockaddr_in, sin_addr)) || - !rn_inithead((void **)&kt->pfrkt_ip6, + !rn_inithead(&kt->pfrkt_ip6, offsetof(struct sockaddr_in6, sin6_addr))) { pfr_destroy_ktable(kt, 0); return (NULL); @@ -2046,10 +2046,8 @@ pfr_destroy_ktable(struct pfr_ktable *kt pfr_clean_node_mask(kt, &addrq); pfr_destroy_kentries(&addrq); } - if (kt->pfrkt_ip4 != NULL) - free((caddr_t)kt->pfrkt_ip4, M_RTABLE, 0); - if (kt->pfrkt_ip6 != NULL) - free((caddr_t)kt->pfrkt_ip6, M_RTABLE, 0); + rn_freehead(kt->pfrkt_ip4); + rn_freehead(kt->pfrkt_ip6); if (kt->pfrkt_shadow != NULL) pfr_destroy_ktable(kt->pfrkt_shadow, flushaddr); if (kt->pfrkt_rs != NULL) { Index: net/pipex.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/net/pipex.c,v retrieving revision 1.102 diff -u -p -r1.102 pipex.c --- net/pipex.c 6 Jun 2017 13:07:22 -0000 1.102 +++ net/pipex.c 4 Jul 2017 16:30:17 -0000 @@ -151,12 +151,12 @@ pipex_iface_init(struct pipex_iface_cont pipex_iface->ifnet_this = ifp; if (pipex_rd_head4 == NULL) { - if (!rn_inithead((void **)&pipex_rd_head4, + if (!rn_inithead(&pipex_rd_head4, offsetof(struct sockaddr_in, sin_addr))) panic("rn_inithead() failed on pipex_init()"); } if (pipex_rd_head6 == NULL) { - if (!rn_inithead((void **)&pipex_rd_head6, + if (!rn_inithead(&pipex_rd_head6, offsetof(struct sockaddr_in6, sin6_addr))) panic("rn_inithead() failed on pipex_init()"); } Index: net/radix.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/net/radix.c,v retrieving revision 1.58 diff -u -p -r1.58 radix.c --- net/radix.c 20 Jun 2017 09:03:39 -0000 1.58 +++ net/radix.c 4 Jul 2017 16:30:17 -0000 @@ -60,7 +60,8 @@ static unsigned int max_keylen; /* size struct radix_node_head *mask_rnhead; /* head of shared mask tree */ -struct pool rtmask_pool; /* pool for radix_mask structures */ +struct pool rthead_pool; /* pool for radix_node_head structs */ +struct pool rtmask_pool; /* pool for radix_mask structs */ static inline int rn_satisfies_leaf(char *, struct radix_node *, int); static inline int rn_lexobetter(void *, void *); @@ -1097,7 +1098,7 @@ rn_initmask(void) KASSERT(max_keylen > 0); - mask_rnhead = malloc(sizeof(*mask_rnhead), M_RTABLE, M_NOWAIT); + mask_rnhead = pool_get(&rthead_pool, PR_NOWAIT); if (mask_rnhead == NULL) return (1); @@ -1106,7 +1107,7 @@ rn_initmask(void) } int -rn_inithead(void **head, int off) +rn_inithead(struct radix_node_head **head, int off) { struct radix_node_head *rnh; @@ -1116,7 +1117,7 @@ rn_inithead(void **head, int off) if (rn_initmask()) panic("failed to initialize the mask tree"); - rnh = malloc(sizeof(*rnh), M_RTABLE, M_NOWAIT); + rnh = pool_get(&rthead_pool, PR_NOWAIT); if (rnh == NULL) return (0); *head = rnh; @@ -1124,6 +1125,14 @@ rn_inithead(void **head, int off) return (1); } +void +rn_freehead(struct radix_node_head *rnh) +{ + if (rnh == NULL) + return; + pool_put(&rthead_pool, rnh); +} + int rn_inithead0(struct radix_node_head *rnh, int offset) { @@ -1158,6 +1167,8 @@ rn_init(unsigned int keylen) if (max_keylen == 0) { pool_init(&rtmask_pool, sizeof(struct radix_mask), 0, IPL_SOFTNET, 0, "rtmask", NULL); + pool_init(&rthead_pool, sizeof(struct radix_node_head), 0, + IPL_SOFTNET, 0, "rthead", NULL); } if (keylen <= max_keylen) Index: net/radix.h =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/net/radix.h,v retrieving revision 1.30 diff -u -p -r1.30 radix.h --- net/radix.h 19 Jun 2017 09:42:45 -0000 1.30 +++ net/radix.h 4 Jul 2017 16:30:17 -0000 @@ -97,7 +97,8 @@ struct radix_node_head { }; void rn_init(unsigned int); -int rn_inithead(void **, int); +int rn_inithead(struct radix_node_head **, int); +void rn_freehead(struct radix_node_head *); int rn_walktree(struct radix_node_head *, int (*)(struct radix_node *, void *, u_int), void *); Index: netinet/ip_spd.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_spd.c,v retrieving revision 1.92 diff -u -p -r1.92 ip_spd.c --- netinet/ip_spd.c 6 Apr 2017 14:25:18 -0000 1.92 +++ netinet/ip_spd.c 4 Jul 2017 16:30:17 -0000 @@ -98,7 +98,7 @@ spd_table_add(unsigned int rtableid) } if (spd_tables[rdomain] == NULL) { - if (rn_inithead((void **)&rnh, + if (rn_inithead(&rnh, offsetof(struct sockaddr_encap, sen_type)) == 0) rnh = NULL; spd_tables[rdomain] = rnh;