diff options
author | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2001-02-21 17:22:06 +0000 |
---|---|---|
committer | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2001-02-21 17:22:06 +0000 |
commit | f2132ef3d7e0cc16e2af76cc163c11d21fd04d1f (patch) | |
tree | 7473e24e896192d0430a0c6668f33357b409f533 | |
parent | 81e2483802b2414cb711b9ce30adf852ea76e70f (diff) |
make validation code more strict for ND6/dest6 variable length headers.
check duplicated nd6_ifinfo table initialization in a better way.
sync with kame
-rw-r--r-- | sys/netinet6/dest6.c | 19 | ||||
-rw-r--r-- | sys/netinet6/nd6.c | 32 |
2 files changed, 33 insertions, 18 deletions
diff --git a/sys/netinet6/dest6.c b/sys/netinet6/dest6.c index cca97912931..63328823a57 100644 --- a/sys/netinet6/dest6.c +++ b/sys/netinet6/dest6.c @@ -1,5 +1,5 @@ -/* $OpenBSD: dest6.c,v 1.6 2001/02/16 15:57:58 itojun Exp $ */ -/* $KAME: dest6.c,v 1.23 2001/01/23 13:32:26 itojun Exp $ */ +/* $OpenBSD: dest6.c,v 1.7 2001/02/21 17:22:05 itojun Exp $ */ +/* $KAME: dest6.c,v 1.24 2001/02/21 16:12:35 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -88,22 +88,19 @@ dest6_input(mp, offp, proto) /* search header for all options. */ for (optlen = 0; dstoptlen > 0; dstoptlen -= optlen, opt += optlen) { - switch(*opt) { + if (*opt != IP6OPT_PAD1 && dstoptlen < IP6OPT_MINLEN) { + ip6stat.ip6s_toosmall++; + goto bad; + } + + switch (*opt) { case IP6OPT_PAD1: optlen = 1; break; case IP6OPT_PADN: - if (dstoptlen < IP6OPT_MINLEN) { - ip6stat.ip6s_toosmall++; - goto bad; - } optlen = *(opt + 1) + 2; break; default: /* unknown option */ - if (dstoptlen < IP6OPT_MINLEN) { - ip6stat.ip6s_toosmall++; - goto bad; - } if ((optlen = ip6_unknown_opt(opt, m, opt-mtod(m, u_int8_t *))) == -1) return(IPPROTO_DONE); diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index c7f72da2688..5f069b783c0 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -1,5 +1,5 @@ -/* $OpenBSD: nd6.c,v 1.26 2001/02/16 16:00:00 itojun Exp $ */ -/* $KAME: nd6.c,v 1.126 2001/02/16 12:49:45 itojun Exp $ */ +/* $OpenBSD: nd6.c,v 1.27 2001/02/21 17:22:05 itojun Exp $ */ +/* $KAME: nd6.c,v 1.131 2001/02/21 16:28:18 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -169,8 +169,14 @@ nd6_ifattach(ifp) #define ND nd_ifinfo[ifp->if_index] - /* don't initialize if called twice */ - if (ND.linkmtu) + /* + * Don't initialize if called twice. + * XXX: to detect this, we should choose a member that is never set + * before initialization of the ND structure itself. We formaly used + * the linkmtu member, which was not suitable because it could be + * initialized via "ifconfig mtu". + */ + if (ND.basereachable) return; ND.linkmtu = ifindex2ifnet[ifp->if_index]->if_mtu; @@ -275,6 +281,12 @@ nd6_option(ndopts) nd_opt = ndopts->nd_opts_search; + /* make sure nd_opt_len is inside the buffer */ + if ((caddr_t)&nd_opt->nd_opt_len >= (caddr_t)ndopts->nd_opts_last) { + bzero(ndopts, sizeof(*ndopts)); + return NULL; + } + olen = nd_opt->nd_opt_len << 3; if (olen == 0) { /* @@ -286,7 +298,12 @@ nd6_option(ndopts) } ndopts->nd_opts_search = (struct nd_opt_hdr *)((caddr_t)nd_opt + olen); - if (!(ndopts->nd_opts_search < ndopts->nd_opts_last)) { + if (ndopts->nd_opts_search > ndopts->nd_opts_last) { + /* option overruns the end of buffer, invalid */ + bzero(ndopts, sizeof(*ndopts)); + return NULL; + } else if (ndopts->nd_opts_search == ndopts->nd_opts_last) { + /* reached the end of options chain */ ndopts->nd_opts_done = 1; ndopts->nd_opts_search = NULL; } @@ -333,8 +350,9 @@ nd6_options(ndopts) case ND_OPT_MTU: case ND_OPT_REDIRECTED_HEADER: if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) { - printf("duplicated ND6 option found " - "(type=%d)\n", nd_opt->nd_opt_type); + nd6log((LOG_INFO, + "duplicated ND6 option found (type=%d)\n", + nd_opt->nd_opt_type)); /* XXX bark? */ } else { ndopts->nd_opt_array[nd_opt->nd_opt_type] |