From 8937ddef336b132809620ffd7e56921c84e867ef Mon Sep 17 00:00:00 2001 From: itojun Date: Fri, 10 Mar 2000 14:47:12 +0000 Subject: [PATCH] do not touch radix_node with RNF_ROOT on route_output(). this can cause kernel panic (by non-root invocation of route(8)) on certain routing table setup. KAME PR: 217 --- sys/net/route.c | 5 ++++- sys/net/rtsock.c | 20 ++++++++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/sys/net/route.c b/sys/net/route.c index e7aba3239c03..b023ab190fa3 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -1,4 +1,4 @@ -/* $NetBSD: route.c,v 1.31 2000/02/02 18:02:08 thorpej Exp $ */ +/* $NetBSD: route.c,v 1.32 2000/03/10 14:47:12 itojun Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -531,6 +531,7 @@ rt_setgate(rt0, dst, gate) R_Malloc(new, caddr_t, dlen + glen); if (new == 0) return 1; + Bzero(new, dlen + glen); rt->rt_nodes->rn_key = new; } else { new = rt->rt_nodes->rn_key; @@ -695,6 +696,7 @@ rt_timer_queue_create(timeout) R_Malloc(rtq, struct rttimer_queue *, sizeof *rtq); if (rtq == NULL) return (NULL); + Bzero(rtq, sizeof *rtq); rtq->rtq_timeout = timeout; TAILQ_INIT(&rtq->rtq_head); @@ -779,6 +781,7 @@ rt_timer_add(rt, func, queue) r = pool_get(&rttimer_pool, PR_NOWAIT); if (r == NULL) return (ENOBUFS); + Bzero(r, sizeof(*r)); r->rtt_rt = rt; r->rtt_time = current_time; diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index e6e45c7c2690..43e6f669ee74 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -1,4 +1,4 @@ -/* $NetBSD: rtsock.c,v 1.36 2000/03/06 20:49:00 thorpej Exp $ */ +/* $NetBSD: rtsock.c,v 1.37 2000/03/10 14:47:13 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -203,6 +203,7 @@ route_output(m, va_alist) #endif { register struct rt_msghdr *rtm = 0; + register struct radix_node *rn; register struct rtentry *rt = 0; struct rtentry *saved_nrt = 0; struct radix_node_head *rnh; @@ -217,8 +218,8 @@ route_output(m, va_alist) so = va_arg(ap, struct socket *); va_end(ap); - -#define senderr(e) { error = e; goto flush;} + bzero(&info, sizeof(info)); +#define senderr(e) do { error = e; goto flush;} while (0) if (m == 0 || ((m->m_len < sizeof(int32_t)) && (m = m_pullup(m, sizeof(int32_t))) == 0)) return (ENOBUFS); @@ -293,11 +294,14 @@ route_output(m, va_alist) case RTM_LOCK: if ((rnh = rt_tables[dst->sa_family]) == 0) { senderr(EAFNOSUPPORT); - } else if ((rt = (struct rtentry *) - rnh->rnh_lookup(dst, netmask, rnh)) != NULL) - rt->rt_refcnt++; - else + } + rn = rnh->rnh_lookup(dst, netmask, rnh); + if (rn == NULL || (rn->rn_flags & RNF_ROOT) != 0) { senderr(ESRCH); + } + rt = (struct rtentry *)rn; + rt->rt_refcnt++; + switch(rtm->rtm_type) { case RTM_GET: @@ -318,7 +322,7 @@ route_output(m, va_alist) } else { ifpaddr = 0; ifaaddr = 0; - } + } } (void)rt_msg2(rtm->rtm_type, &info, (caddr_t)0, (struct walkarg *)0, &len);