- icmp6 nodeinfo: remove possibility of unaligned pointer access.

- jumbo payload output: fix incorrect mbuf manipulation
- pedant: align issues, mbuf assumption
(sync with kame)
This commit is contained in:
itojun 2000-08-19 08:15:53 +00:00
parent 97d171d025
commit cabceaa265
3 changed files with 107 additions and 31 deletions

View File

@ -1,9 +1,10 @@
/* $NetBSD: net_osdep.h,v 1.2 1999/12/13 15:17:19 itojun Exp $ */
/* $NetBSD: net_osdep.h,v 1.3 2000/08/19 08:15:53 itojun Exp $ */
/* $KAME: net_osdep.h,v 1.23 2000/08/19 00:58:11 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@ -15,7 +16,7 @@
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@ -35,11 +36,25 @@
/*
* OS dependencies:
*
* - struct rt_addrinfo
* all *BSDs except bsdi4 only have two members; rti_addrs and rti_info[].
* bsdi4 has additional members; rti_flags, rti_ifa, rti_ifp, and rti_rtm.
*
* - side effects of rtrequest[1](RTM_DELETE)
* BSDI[34]: delete all cloned routes underneath the route.
* FreeBSD[234]: delete all protocol-cloned routes underneath the route.
* note that cloned routes from an interface direct route
* still remain.
* NetBSD, OpenBSD: no side effects.
* - privileged process
* NetBSD, FreeBSD 3
* struct proc *p;
* if (p && !suser(p->p_ucred, &p->p_acflag))
* privileged;
* FreeBSD 4
* struct proc *p;
* if (p && !suser(p))
* privileged;
* OpenBSD, BSDI [34], FreeBSD 2
* struct socket *so;
* if (so->so_state & SS_PRIV)
@ -64,7 +79,7 @@
* BSDI [34] no old standard if_name+unit
* - usrreq
* NetBSD, OpenBSD, BSDI [34], FreeBSD 2
* single function with PRU_xx, arguments are mbuf
* single function with PRU_xx, arguments are mbuf
* FreeBSD 3
* separates functions, non-mbuf arguments
* - {set,get}sockopt
@ -114,6 +129,34 @@
*
* odd thing is that many of them refers loif as ifnet *loif,
* not loif[NLOOP], from outside of if_loop.c.
*
* - number of bpf pseudo devices
* others: bpfilter.h, NBPFILTER
* FreeBSD4: bpf.h, NBPF
* solution:
* #if defined(__FreeBSD__) && __FreeBSD__ >= 4
* #include "bpf.h"
* #define NBPFILTER NBPF
* #else
* #include "bpfilter.h"
* #endif
*
* - protosw for IPv4 (sys/netinet)
* FreeBSD4: struct ipprotosw in netinet/ipprotosw.h
* others: struct protosw in sys/protosw.h
*
* - header files with defopt (opt_xx.h)
* FreeBSD3: opt_{inet,ipsec,ip6fw,altq}.h
* FreeBSD4: opt_{inet,inet6,ipsec,ip6fw,altq}.h
* NetBSD: opt_{inet,ipsec,altq}.h
* others: does not use defopt
*
* - IN_MULTICAST/IN_CLASS[A-D] macro.
* OpenBSD and NetBSD: net endian (kernel) or host endian (userland)
* others: always host endian
*
* - (m->m_flags & M_EXT) != 0 does *not* mean that the max data length of
* the mbuf == MCLBYTES.
*/
#ifndef __NET_NET_OSDEP_H_DEFINED_

View File

@ -1,5 +1,5 @@
/* $NetBSD: icmp6.c,v 1.41 2000/08/03 16:30:38 itojun Exp $ */
/* $KAME: icmp6.c,v 1.131 2000/08/03 15:24:34 itojun Exp $ */
/* $NetBSD: icmp6.c,v 1.42 2000/08/19 08:15:54 itojun Exp $ */
/* $KAME: icmp6.c,v 1.134 2000/08/19 02:01:46 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -1282,11 +1282,15 @@ ni6_input(m, off)
nni6->ni_flags = 0;
break;
case NI_QTYPE_SUPTYPES:
{
u_int32_t v;
nni6->ni_code = ICMP6_NI_SUCCESS;
nni6->ni_flags = htons(0x0000); /* raw bitmap */
/* supports NOOP, SUPTYPES, FQDN, and NODEADDR */
*(u_int32_t *)(nni6 + 1) = htonl(0x0000000f);
v = (u_int32_t)htonl(0x0000000f);
bcopy(&v, nni6 + 1, sizeof(u_int32_t));
break;
}
case NI_QTYPE_FQDN:
nni6->ni_code = ICMP6_NI_SUCCESS;
fqdn = (struct ni_reply_fqdn *)(mtod(n, caddr_t) +
@ -1310,12 +1314,9 @@ ni6_input(m, off)
int lenlim, copied;
nni6->ni_code = ICMP6_NI_SUCCESS;
if (n->m_flags & M_EXT)
lenlim = MCLBYTES - sizeof(struct ip6_hdr) -
sizeof(struct icmp6_nodeinfo);
else
lenlim = MHLEN - sizeof(struct ip6_hdr) -
sizeof(struct icmp6_nodeinfo);
n->m_pkthdr.len = n->m_len =
sizeof(struct ip6_hdr) + sizeof(struct icmp6_nodeinfo);
lenlim = M_TRAILINGSPACE(n);
copied = ni6_store_addrs(ni6, nni6, ifp, lenlim);
/* XXX: reset mbuf length */
n->m_pkthdr.len = n->m_len = sizeof(struct ip6_hdr) +
@ -2223,7 +2224,8 @@ icmp6_redirect_output(m0, rt)
MCLGET(m, M_DONTWAIT);
if (!m)
goto fail;
maxlen = (m->m_flags & M_EXT) ? MCLBYTES : MHLEN;
m->m_len = 0;
maxlen = M_TRAILINGSPACE(m);
maxlen = min(IPV6_MMTU, maxlen);
/* just for safety */
if (maxlen < sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr) +

View File

@ -1,5 +1,5 @@
/* $NetBSD: ip6_output.c,v 1.24 2000/07/06 12:51:41 itojun Exp $ */
/* $KAME: ip6_output.c,v 1.115 2000/07/03 13:23:28 itojun Exp $ */
/* $NetBSD: ip6_output.c,v 1.25 2000/08/19 08:15:54 itojun Exp $ */
/* $KAME: ip6_output.c,v 1.122 2000/08/19 02:12:02 jinmei Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -419,7 +419,7 @@ skip_ipsec2:;
ip6->ip6_dst = rh0->ip6r0_addr[0];
bcopy((caddr_t)&rh0->ip6r0_addr[1],
(caddr_t)&rh0->ip6r0_addr[0],
sizeof(struct in6_addr)*(rh0->ip6r0_segleft - 1)
sizeof(struct in6_addr) * (rh0->ip6r0_segleft - 1)
);
rh0->ip6r0_addr[rh0->ip6r0_segleft - 1] = finaldst;
break;
@ -1084,6 +1084,7 @@ ip6_insert_jumboopt(exthdrs, plen)
{
struct mbuf *mopt;
u_char *optbuf;
u_int32_t v;
#define JUMBOOPTLEN 8 /* length of jumbo payload option and padding */
@ -1106,18 +1107,42 @@ ip6_insert_jumboopt(exthdrs, plen)
mopt = exthdrs->ip6e_hbh;
if (M_TRAILINGSPACE(mopt) < JUMBOOPTLEN) {
caddr_t oldoptp = mtod(mopt, caddr_t);
/*
* XXX assumption:
* - exthdrs->ip6e_hbh is not referenced from places
* other than exthdrs.
* - exthdrs->ip6e_hbh is not an mbuf chain.
*/
int oldoptlen = mopt->m_len;
struct mbuf *n;
if (mopt->m_flags & M_EXT)
return(ENOBUFS); /* XXX */
MCLGET(mopt, M_DONTWAIT);
if ((mopt->m_flags & M_EXT) == 0)
/*
* XXX: give up if the whole (new) hbh header does
* not fit even in an mbuf cluster.
*/
if (oldoptlen + JUMBOOPTLEN > MCLBYTES)
return(ENOBUFS);
bcopy(oldoptp, mtod(mopt, caddr_t), oldoptlen);
optbuf = mtod(mopt, caddr_t) + oldoptlen;
mopt->m_len = oldoptlen + JUMBOOPTLEN;
/*
* As a consequence, we must always prepare a cluster
* at this point.
*/
MGET(n, M_DONTWAIT, MT_DATA);
if (n) {
MCLGET(n, M_DONTWAIT);
if ((n->m_flags & M_EXT) == 0) {
m_freem(n);
n = NULL;
}
}
if (!n)
return(ENOBUFS);
n->m_len = oldoptlen + JUMBOOPTLEN;
bcopy(mtod(mopt, caddr_t), mtod(n, caddr_t),
oldoptlen);
optbuf = mtod(n, caddr_t) + oldoptlen;
m_freem(mopt);
exthdrs->ip6e_hbh = n;
} else {
optbuf = mtod(mopt, u_char *) + mopt->m_len;
mopt->m_len += JUMBOOPTLEN;
@ -1136,7 +1161,8 @@ ip6_insert_jumboopt(exthdrs, plen)
/* fill in the option. */
optbuf[2] = IP6OPT_JUMBO;
optbuf[3] = 4;
*(u_int32_t *)&optbuf[4] = htonl(plen + JUMBOOPTLEN);
v = (u_int32_t)htonl(plen + JUMBOOPTLEN);
bcopy(&v, &optbuf[4], sizeof(u_int32_t));
/* finally, adjust the packet header length */
exthdrs->ip6e_ip6->m_pkthdr.len += JUMBOOPTLEN;
@ -1618,7 +1644,7 @@ ip6_setmoptions(optname, im6op, m)
error = EINVAL;
break;
}
ifindex = *(mtod(m, u_int *));
bcopy(mtod(m, u_int *), &ifindex, sizeof(ifindex));
if (ifindex < 0 || if_index < ifindex) {
error = ENXIO; /* XXX EINVAL? */
break;
@ -1641,7 +1667,7 @@ ip6_setmoptions(optname, im6op, m)
error = EINVAL;
break;
}
optval = *(mtod(m, u_int *));
bcopy(mtod(m, u_int *), &optval, sizeof(optval));
if (optval < -1 || optval >= 256)
error = EINVAL;
else if (optval == -1)
@ -1656,8 +1682,12 @@ ip6_setmoptions(optname, im6op, m)
* Set the loopback flag for outgoing multicast packets.
* Must be zero or one.
*/
if (m == NULL || m->m_len != sizeof(u_int) ||
(loop = *(mtod(m, u_int *))) > 1) {
if (m == NULL || m->m_len != sizeof(u_int)) {
error = EINVAL;
break;
}
bcopy(mtod(m, u_int *), &loop, sizeof(loop));
if (loop > 1) {
error = EINVAL;
break;
}
@ -2007,7 +2037,8 @@ ip6_setpktoptions(control, opt, priv)
if (cm->cmsg_len != CMSG_LEN(sizeof(int)))
return(EINVAL);
opt->ip6po_hlim = *(int *)CMSG_DATA(cm);
bcopy(CMSG_DATA(cm), &opt->ip6po_hlim,
sizeof(opt->ip6po_hlim));
if (opt->ip6po_hlim < -1 || opt->ip6po_hlim > 255)
return(EINVAL);
break;