summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2015-11-09 12:15:30 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2015-11-09 12:15:30 +0000
commitf14a9ba0ac2b5f84f20415bae9199fd48b0ab259 (patch)
tree8afa0092ea50b3e6def5234ebfc3d0fe55c50da6 /sys
parent45be7ac5ce7032c92c1d7217d61126eec9c2f7ae (diff)
Do not leave dangling pointers in the ART tree in case of memory
exhaustion. Reported by benno@ and found thanks to his bgpd(8) test setup.
Diffstat (limited to 'sys')
-rw-r--r--sys/net/rtable.c40
1 files changed, 20 insertions, 20 deletions
diff --git a/sys/net/rtable.c b/sys/net/rtable.c
index 150588304cb..9f7dcf08496 100644
--- a/sys/net/rtable.c
+++ b/sys/net/rtable.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtable.c,v 1.22 2015/11/06 17:55:55 mpi Exp $ */
+/* $OpenBSD: rtable.c,v 1.23 2015/11/09 12:15:29 mpi Exp $ */
/*
* Copyright (c) 2014-2015 Martin Pieuchot
@@ -623,6 +623,23 @@ rtable_insert(unsigned int rtableid, struct sockaddr *dst,
}
#endif
+ /*
+ * XXX Allocating a sockaddr for the mask per node wastes a lot
+ * of memory, thankfully we'll get rid of that when rt_mask()
+ * will be no more.
+ */
+ if (mask != NULL) {
+ struct sockaddr *msk;
+
+ msk = malloc(dst->sa_len, M_RTABLE, M_NOWAIT | M_ZERO);
+ if (msk == NULL) {
+ error = ENOMEM;
+ goto out;
+ }
+ memcpy(msk, mask, dst->sa_len);
+ rt->rt_mask = msk;
+ }
+
an = pool_get(&an_pool, PR_NOWAIT | PR_ZERO);
if (an == NULL) {
error = ENOBUFS;
@@ -634,6 +651,8 @@ rtable_insert(unsigned int rtableid, struct sockaddr *dst,
prev = art_insert(ar, an, addr, plen);
if (prev == NULL) {
+ free(rt->rt_mask, M_RTABLE, 0);
+ rt->rt_mask = NULL;
pool_put(&an_pool, an);
error = ESRCH;
goto out;
@@ -675,25 +694,6 @@ rtable_insert(unsigned int rtableid, struct sockaddr *dst,
rt->rt_node = an;
rt->rt_dest = dst;
-
- /*
- * XXX Allocating a sockaddr for the mask per node wastes a lot
- * of memory, thankfully we'll get rid of that when rt_mask()
- * will be no more.
- */
- if (mask != NULL) {
- struct sockaddr *msk;
-
- msk = malloc(dst->sa_len, M_RTABLE, M_NOWAIT | M_ZERO);
- if (msk == NULL) {
- pool_put(&an_pool, an);
- error = ENOMEM;
- goto out;
- }
- memcpy(msk, mask, dst->sa_len);
- rt->rt_mask = msk;
- }
-
rtref(rt);
SLIST_INSERT_HEAD(&an->an_rtlist, rt, rt_next);