diff options
author | trociny <trociny@FreeBSD.org> | 2011-11-06 09:29:52 +0000 |
---|---|---|
committer | trociny <trociny@FreeBSD.org> | 2011-11-06 09:29:52 +0000 |
commit | ddbde914da94b7822affd2f7a4d229a6df022334 (patch) | |
tree | 454655fd47b3c4b69bcabb34add1244bca0a1667 /sys/netinet6 | |
parent | a22bc64df75dd7be93fb8e85e95dcb21c5eeed7f (diff) | |
download | FreeBSD-src-ddbde914da94b7822affd2f7a4d229a6df022334.zip FreeBSD-src-ddbde914da94b7822affd2f7a4d229a6df022334.tar.gz |
Before dereferencing intotw() check for NULL, the same way as it is
done for in_pcb (see r157474).
MFC after: 1 week
Diffstat (limited to 'sys/netinet6')
-rw-r--r-- | sys/netinet6/in6_pcb.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index d15c605..b0326bc 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -187,6 +187,7 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam, } if (lport) { struct inpcb *t; + struct tcptw *tw; /* GROSS */ if (ntohs(lport) <= V_ipport_reservedhigh && @@ -233,10 +234,21 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam, } t = in6_pcblookup_local(pcbinfo, &sin6->sin6_addr, lport, lookupflags, cred); - if (t && (reuseport & ((t->inp_flags & INP_TIMEWAIT) ? - intotw(t)->tw_so_options : - t->inp_socket->so_options)) == 0) + if (t && (t->inp_flags & INP_TIMEWAIT)) { + /* + * XXXRW: If an incpb has had its timewait + * state recycled, we treat the address as + * being in use (for now). This is better + * than a panic, but not desirable. + */ + tw = intotw(t); + if (tw == NULL || + (reuseport & tw->tw_so_options) == 0) + return (EADDRINUSE); + } else if (t && (reuseport & t->inp_socket->so_options) + == 0) { return (EADDRINUSE); + } #ifdef INET if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0 && IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { @@ -246,9 +258,11 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam, t = in_pcblookup_local(pcbinfo, sin.sin_addr, lport, lookupflags, cred); if (t && t->inp_flags & INP_TIMEWAIT) { - if ((reuseport & - intotw(t)->tw_so_options) == 0 && - (ntohl(t->inp_laddr.s_addr) != + tw = intotw(t); + if (tw == NULL) + return (EADDRINUSE); + if ((reuseport & tw->tw_so_options) == 0 + && (ntohl(t->inp_laddr.s_addr) != INADDR_ANY || ((inp->inp_vflag & INP_IPV6PROTO) == (t->inp_vflag & INP_IPV6PROTO)))) |