Fix a panic possibility caused by returning without releasing locks.
It was fixed by moving problemetic checks, as well as checks that doesn't need locking before locks are acquired. Submitted by: Ryan Sommers <ryans@gamersimpact.com> In co-operation with: cperciva, maxim, mlaier, sam Tested by: submitter (previous patch), me (current patch) Reviewed by: cperciva, mlaier (previous patch), sam (current patch) Approved by: sam Dedicated to: enough!
This commit is contained in:
parent
1c38ed81bc
commit
52710de1cb
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=127862
@ -238,20 +238,18 @@ tcp_usr_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
struct sockaddr_in *sinp;
|
||||
const int inirw = INI_WRITE;
|
||||
|
||||
COMMON_START();
|
||||
|
||||
sinp = (struct sockaddr_in *)nam;
|
||||
if (nam->sa_len != sizeof (*sinp))
|
||||
return (EINVAL);
|
||||
/*
|
||||
* Must check for multicast addresses and disallow binding
|
||||
* to them.
|
||||
*/
|
||||
sinp = (struct sockaddr_in *)nam;
|
||||
if (nam->sa_len != sizeof (*sinp))
|
||||
return (EINVAL);
|
||||
if (sinp->sin_family == AF_INET &&
|
||||
IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) {
|
||||
error = EAFNOSUPPORT;
|
||||
goto out;
|
||||
}
|
||||
IN_MULTICAST(ntohl(sinp->sin_addr.s_addr)))
|
||||
return (EAFNOSUPPORT);
|
||||
|
||||
COMMON_START();
|
||||
error = in_pcbbind(inp, nam, td->td_ucred);
|
||||
if (error)
|
||||
goto out;
|
||||
@ -269,20 +267,18 @@ tcp6_usr_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
struct sockaddr_in6 *sin6p;
|
||||
const int inirw = INI_WRITE;
|
||||
|
||||
COMMON_START();
|
||||
|
||||
sin6p = (struct sockaddr_in6 *)nam;
|
||||
if (nam->sa_len != sizeof (*sin6p))
|
||||
return (EINVAL);
|
||||
/*
|
||||
* Must check for multicast addresses and disallow binding
|
||||
* to them.
|
||||
*/
|
||||
sin6p = (struct sockaddr_in6 *)nam;
|
||||
if (nam->sa_len != sizeof (*sin6p))
|
||||
return (EINVAL);
|
||||
if (sin6p->sin6_family == AF_INET6 &&
|
||||
IN6_IS_ADDR_MULTICAST(&sin6p->sin6_addr)) {
|
||||
error = EAFNOSUPPORT;
|
||||
goto out;
|
||||
}
|
||||
IN6_IS_ADDR_MULTICAST(&sin6p->sin6_addr))
|
||||
return (EAFNOSUPPORT);
|
||||
|
||||
COMMON_START();
|
||||
inp->inp_vflag &= ~INP_IPV4;
|
||||
inp->inp_vflag |= INP_IPV6;
|
||||
if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
|
||||
@ -366,23 +362,19 @@ tcp_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
struct sockaddr_in *sinp;
|
||||
const int inirw = INI_WRITE;
|
||||
|
||||
COMMON_START();
|
||||
|
||||
/*
|
||||
* Must disallow TCP ``connections'' to multicast addresses.
|
||||
*/
|
||||
sinp = (struct sockaddr_in *)nam;
|
||||
if (nam->sa_len != sizeof (*sinp))
|
||||
return (EINVAL);
|
||||
/*
|
||||
* Must disallow TCP ``connections'' to multicast addresses.
|
||||
*/
|
||||
if (sinp->sin_family == AF_INET
|
||||
&& IN_MULTICAST(ntohl(sinp->sin_addr.s_addr))) {
|
||||
error = EAFNOSUPPORT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
&& IN_MULTICAST(ntohl(sinp->sin_addr.s_addr)))
|
||||
return (EAFNOSUPPORT);
|
||||
if (td && jailed(td->td_ucred))
|
||||
prison_remote_ip(td->td_ucred, 0, &sinp->sin_addr.s_addr);
|
||||
|
||||
COMMON_START();
|
||||
if ((error = tcp_connect(tp, nam, td)) != 0)
|
||||
goto out;
|
||||
error = tcp_output(tp);
|
||||
@ -400,20 +392,17 @@ tcp6_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
|
||||
struct sockaddr_in6 *sin6p;
|
||||
const int inirw = INI_WRITE;
|
||||
|
||||
COMMON_START();
|
||||
|
||||
/*
|
||||
* Must disallow TCP ``connections'' to multicast addresses.
|
||||
*/
|
||||
sin6p = (struct sockaddr_in6 *)nam;
|
||||
if (nam->sa_len != sizeof (*sin6p))
|
||||
return (EINVAL);
|
||||
/*
|
||||
* Must disallow TCP ``connections'' to multicast addresses.
|
||||
*/
|
||||
if (sin6p->sin6_family == AF_INET6
|
||||
&& IN6_IS_ADDR_MULTICAST(&sin6p->sin6_addr)) {
|
||||
error = EAFNOSUPPORT;
|
||||
goto out;
|
||||
}
|
||||
&& IN6_IS_ADDR_MULTICAST(&sin6p->sin6_addr))
|
||||
return (EAFNOSUPPORT);
|
||||
|
||||
COMMON_START();
|
||||
if (IN6_IS_ADDR_V4MAPPED(&sin6p->sin6_addr)) {
|
||||
struct sockaddr_in sin;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user