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;