From f14a9ba0ac2b5f84f20415bae9199fd48b0ab259 Mon Sep 17 00:00:00 2001 From: Martin Pieuchot Date: Mon, 9 Nov 2015 12:15:30 +0000 Subject: 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. --- sys/net/rtable.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'sys') 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); -- cgit v1.2.3