From 99b45486789f345b6d9c4f93cfde2b2a22983469 Mon Sep 17 00:00:00 2001 From: julian Date: Fri, 18 Jul 1997 11:44:24 +0000 Subject: An actual fix for the routing default crashes that 1/ is compatible with the old route(1) in case needed. 2/ actually fixes the problem while vetting bad user input. note: I have already fixed route(1) so the problem shouldn't occur. if it does. use 0.0.0.0/0 instead of the word 'default' :) --- sys/net/rtsock.c | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) (limited to 'sys/net/rtsock.c') diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index f9e1b06..a73baa0 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)rtsock.c 8.5 (Berkeley) 11/2/94 - * $Id: rtsock.c,v 1.29 1997/07/16 14:55:14 julian Exp $ + * $Id: rtsock.c,v 1.30 1997/07/17 09:21:34 msmith Exp $ */ @@ -53,6 +53,7 @@ static struct sockaddr route_dst = { 2, PF_ROUTE, }; static struct sockaddr route_src = { 2, PF_ROUTE, }; +static struct sockaddr sa_zero = { sizeof(sa_zero), AF_INET, }; static struct sockproto route_proto = { PF_ROUTE, }; struct walkarg { @@ -66,7 +67,7 @@ static struct mbuf * rt_msg1 __P((int, struct rt_addrinfo *)); static int rt_msg2 __P((int, struct rt_addrinfo *, caddr_t, struct walkarg *)); -static void rt_xaddrs __P((caddr_t, caddr_t, struct rt_addrinfo *)); +static int rt_xaddrs __P((caddr_t, caddr_t, struct rt_addrinfo *)); static int sysctl_dumpentry __P((struct radix_node *rn, void *vw)); static int sysctl_iflist __P((int af, struct walkarg *w)); static int route_output __P((struct mbuf *, struct socket *)); @@ -305,7 +306,10 @@ route_output(m, so) } rtm->rtm_pid = curproc->p_pid; info.rti_addrs = rtm->rtm_addrs; - rt_xaddrs((caddr_t)(rtm + 1), len + (caddr_t)rtm, &info); + if (rt_xaddrs((caddr_t)(rtm + 1), len + (caddr_t)rtm, &info)) { + dst = 0; + senderr(EINVAL); + } if (dst == 0 || (dst->sa_family >= AF_MAX) || (gate != 0 && (gate->sa_family >= AF_MAX))) senderr(EINVAL); @@ -506,11 +510,13 @@ rt_setmetrics(which, in, out) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) + /* * Extract the addresses of the passed sockaddrs. * Do a little sanity checking so as to avoid bad memory references. + * This data is derived straight from userland. */ -static void +static int rt_xaddrs(cp, cplim, rtinfo) register caddr_t cp, cplim; register struct rt_addrinfo *rtinfo; @@ -519,30 +525,34 @@ rt_xaddrs(cp, cplim, rtinfo) register int i; bzero(rtinfo->rti_info, sizeof(rtinfo->rti_info)); - for (i = 0; i < RTAX_MAX; i++) { + for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) { if ((rtinfo->rti_addrs & (1 << i)) == 0) continue; sa = (struct sockaddr *)cp; /* - * It won't fit. Pretend it doesn't exist. - * Would return EINVAL if not void + * It won't fit. */ - if ( (cp + sa->sa_len) > cplim ) - return; - - /* accept it */ - rtinfo->rti_info[i] = sa; - ADVANCE(cp, sa); + if ( (cp + sa->sa_len) > cplim ) { + return (EINVAL); + } /* * there are no more.. quit now * If there are more bits, they are in error. * I've seen this. route(1) can evidently generate these. * This causes kernel to core dump. + * for compatibility, If we see this, point to a safe address. */ - if (sa->sa_len == 0) - return; + if (sa->sa_len == 0) { + rtinfo->rti_info[i] = &sa_zero; + return (0); /* should be EINVAL but for compat */ + } + + /* accept it */ + rtinfo->rti_info[i] = sa; + ADVANCE(cp, sa); } + return (0); } static struct mbuf * -- cgit v1.1