o Make rt_check() function more strict:
- rt0 passed to rt_check() must not be NULL, assert this. - rt returned by rt_check() must be valid locked rtentry, if no error occured. o Modify callers, so that they never pass NULL rt0 to rt_check(). Reviewed by: sam, ume (nd6.c)
This commit is contained in:
parent
e0688f1293
commit
fa253399af
@ -152,14 +152,16 @@ atm_output(struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst,
|
||||
case AF_INET:
|
||||
case AF_INET6:
|
||||
{
|
||||
struct rtentry *rt;
|
||||
struct rtentry *rt = NULL;
|
||||
/*
|
||||
* check route
|
||||
*/
|
||||
error = rt_check(&rt, &rt0, dst);
|
||||
if (error)
|
||||
goto bad;
|
||||
RT_UNLOCK(rt);
|
||||
if (rt0 != NULL) {
|
||||
error = rt_check(&rt, &rt0, dst);
|
||||
if (error)
|
||||
goto bad;
|
||||
RT_UNLOCK(rt);
|
||||
}
|
||||
|
||||
if (dst->sa_family == AF_INET6)
|
||||
etype = ETHERTYPE_IPV6;
|
||||
|
@ -81,7 +81,7 @@ firewire_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
|
||||
{
|
||||
struct fw_com *fc = IFP2FC(ifp);
|
||||
int error, type;
|
||||
struct rtentry *rt;
|
||||
struct rtentry *rt = NULL;
|
||||
struct m_tag *mtag;
|
||||
union fw_encap *enc;
|
||||
struct fw_hwaddr *destfw;
|
||||
@ -103,10 +103,12 @@ firewire_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
|
||||
goto bad;
|
||||
}
|
||||
|
||||
error = rt_check(&rt, &rt0, dst);
|
||||
if (error)
|
||||
goto bad;
|
||||
RT_UNLOCK(rt);
|
||||
if (rt0 != NULL) {
|
||||
error = rt_check(&rt, &rt0, dst);
|
||||
if (error)
|
||||
goto bad;
|
||||
RT_UNLOCK(rt);
|
||||
}
|
||||
|
||||
/*
|
||||
* For unicast, we make a tag to store the lladdr of the
|
||||
|
@ -243,7 +243,7 @@ iso88025_output(ifp, m, dst, rt0)
|
||||
struct iso88025_header *th;
|
||||
struct iso88025_header gen_th;
|
||||
struct sockaddr_dl *sdl = NULL;
|
||||
struct rtentry *rt;
|
||||
struct rtentry *rt = NULL;
|
||||
|
||||
#ifdef MAC
|
||||
error = mac_check_ifnet_transmit(ifp, m);
|
||||
@ -260,10 +260,12 @@ iso88025_output(ifp, m, dst, rt0)
|
||||
|
||||
/* Calculate routing info length based on arp table entry */
|
||||
/* XXX any better way to do this ? */
|
||||
error = rt_check(&rt, &rt0, dst);
|
||||
if (error)
|
||||
goto bad;
|
||||
RT_UNLOCK(rt);
|
||||
if (rt0 != NULL) {
|
||||
error = rt_check(&rt, &rt0, dst);
|
||||
if (error)
|
||||
goto bad;
|
||||
RT_UNLOCK(rt);
|
||||
}
|
||||
|
||||
if (rt && (sdl = (struct sockaddr_dl *)rt->rt_gateway))
|
||||
if (SDL_ISO88025(sdl)->trld_rcf != 0)
|
||||
|
@ -1262,51 +1262,51 @@ rt_check(struct rtentry **lrt, struct rtentry **lrt0, struct sockaddr *dst)
|
||||
struct rtentry *rt0;
|
||||
int error;
|
||||
|
||||
rt0 = *lrt0;
|
||||
rt = rt0;
|
||||
if (rt) {
|
||||
/* NB: the locking here is tortuous... */
|
||||
RT_LOCK(rt);
|
||||
if ((rt->rt_flags & RTF_UP) == 0) {
|
||||
RT_UNLOCK(rt);
|
||||
rt = rtalloc1(dst, 1, 0UL);
|
||||
if (rt != NULL) {
|
||||
RT_REMREF(rt);
|
||||
/* XXX what about if change? */
|
||||
} else
|
||||
senderr(EHOSTUNREACH);
|
||||
rt0 = rt;
|
||||
}
|
||||
/* XXX BSD/OS checks dst->sa_family != AF_NS */
|
||||
if (rt->rt_flags & RTF_GATEWAY) {
|
||||
if (rt->rt_gwroute == NULL)
|
||||
goto lookup;
|
||||
rt = rt->rt_gwroute;
|
||||
RT_LOCK(rt); /* NB: gwroute */
|
||||
if ((rt->rt_flags & RTF_UP) == 0) {
|
||||
rtfree(rt); /* unlock gwroute */
|
||||
rt = rt0;
|
||||
lookup:
|
||||
RT_UNLOCK(rt0);
|
||||
rt = rtalloc1(rt->rt_gateway, 1, 0UL);
|
||||
RT_LOCK(rt0);
|
||||
rt0->rt_gwroute = rt;
|
||||
if (rt == NULL) {
|
||||
RT_UNLOCK(rt0);
|
||||
senderr(EHOSTUNREACH);
|
||||
}
|
||||
}
|
||||
RT_UNLOCK(rt0);
|
||||
}
|
||||
/* XXX why are we inspecting rmx_expire? */
|
||||
error = (rt->rt_flags & RTF_REJECT) &&
|
||||
(rt->rt_rmx.rmx_expire == 0 ||
|
||||
time_second < rt->rt_rmx.rmx_expire);
|
||||
if (error) {
|
||||
RT_UNLOCK(rt);
|
||||
senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
|
||||
}
|
||||
KASSERT(*lrt0 != NULL, ("rt_check"));
|
||||
rt = rt0 = *lrt0;
|
||||
|
||||
/* NB: the locking here is tortuous... */
|
||||
RT_LOCK(rt);
|
||||
if ((rt->rt_flags & RTF_UP) == 0) {
|
||||
RT_UNLOCK(rt);
|
||||
rt = rtalloc1(dst, 1, 0UL);
|
||||
if (rt != NULL) {
|
||||
RT_REMREF(rt);
|
||||
/* XXX what about if change? */
|
||||
} else
|
||||
senderr(EHOSTUNREACH);
|
||||
rt0 = rt;
|
||||
}
|
||||
/* XXX BSD/OS checks dst->sa_family != AF_NS */
|
||||
if (rt->rt_flags & RTF_GATEWAY) {
|
||||
if (rt->rt_gwroute == NULL)
|
||||
goto lookup;
|
||||
rt = rt->rt_gwroute;
|
||||
RT_LOCK(rt); /* NB: gwroute */
|
||||
if ((rt->rt_flags & RTF_UP) == 0) {
|
||||
rtfree(rt); /* unlock gwroute */
|
||||
rt = rt0;
|
||||
lookup:
|
||||
RT_UNLOCK(rt0);
|
||||
rt = rtalloc1(rt->rt_gateway, 1, 0UL);
|
||||
RT_LOCK(rt0);
|
||||
rt0->rt_gwroute = rt;
|
||||
if (rt == NULL) {
|
||||
RT_UNLOCK(rt0);
|
||||
senderr(EHOSTUNREACH);
|
||||
}
|
||||
}
|
||||
RT_UNLOCK(rt0);
|
||||
}
|
||||
/* XXX why are we inspecting rmx_expire? */
|
||||
error = (rt->rt_flags & RTF_REJECT) &&
|
||||
(rt->rt_rmx.rmx_expire == 0 ||
|
||||
time_second < rt->rt_rmx.rmx_expire);
|
||||
if (error) {
|
||||
RT_UNLOCK(rt);
|
||||
senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
|
||||
}
|
||||
|
||||
*lrt = rt;
|
||||
*lrt0 = rt0;
|
||||
return (0);
|
||||
|
@ -2065,6 +2065,12 @@ nd6_storelladdr(ifp, rt0, m, dst, desten)
|
||||
}
|
||||
}
|
||||
|
||||
if (rt0 == NULL) {
|
||||
/* this could happen, if we could not allocate memory */
|
||||
m_freem(m);
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
error = rt_check(&rt, &rt0, dst);
|
||||
if (error) {
|
||||
m_freem(m);
|
||||
|
Loading…
Reference in New Issue
Block a user