Push a possible "unbind" in some situation from in6_pcbsetport() to
callers. This also fixes a problem when the prison call could set the inp->in6p_laddr (laddr) and a following priv_check_cred() call would return an error and will allow us to merge the IPv4 and IPv6 implementation. MFC after: 2 weeks
This commit is contained in:
parent
e3ccdf9a91
commit
5d37412b23
@ -256,8 +256,11 @@ in6_pcbbind(register struct inpcb *inp, struct sockaddr *nam,
|
||||
inp->in6p_laddr = sin6->sin6_addr;
|
||||
}
|
||||
if (lport == 0) {
|
||||
if ((error = in6_pcbsetport(&inp->in6p_laddr, inp, cred)) != 0)
|
||||
if ((error = in6_pcbsetport(&inp->in6p_laddr, inp, cred)) != 0) {
|
||||
/* Undo an address bind that may have occurred. */
|
||||
inp->in6p_laddr = in6addr_any;
|
||||
return (error);
|
||||
}
|
||||
} else {
|
||||
inp->inp_lport = lport;
|
||||
if (in_pcbinshash(inp) != 0) {
|
||||
|
@ -925,11 +925,8 @@ in6_pcbsetport(struct in6_addr *laddr, struct inpcb *inp, struct ucred *cred)
|
||||
count = last - first;
|
||||
|
||||
do {
|
||||
if (count-- < 0) { /* completely used? */
|
||||
/* Undo an address bind that may have occurred. */
|
||||
inp->in6p_laddr = in6addr_any;
|
||||
if (count-- < 0) /* completely used? */
|
||||
return (EADDRNOTAVAIL);
|
||||
}
|
||||
++*lastport;
|
||||
if (*lastport < first || *lastport > last)
|
||||
*lastport = first;
|
||||
|
@ -656,8 +656,11 @@ udp6_output(struct inpcb *inp, struct mbuf *m, struct sockaddr *addr6,
|
||||
goto release;
|
||||
}
|
||||
if (inp->inp_lport == 0 &&
|
||||
(error = in6_pcbsetport(laddr, inp, td->td_ucred)) != 0)
|
||||
(error = in6_pcbsetport(laddr, inp, td->td_ucred)) != 0) {
|
||||
/* Undo an address bind that may have occurred. */
|
||||
inp->in6p_laddr = in6addr_any;
|
||||
goto release;
|
||||
}
|
||||
} else {
|
||||
if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
|
||||
error = ENOTCONN;
|
||||
|
Loading…
x
Reference in New Issue
Block a user