summaryrefslogtreecommitdiffstats
path: root/sys/netinet6
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2006-04-12 03:03:47 +0000
committerrwatson <rwatson@FreeBSD.org>2006-04-12 03:03:47 +0000
commit600ea5a78241ebe923bc0b42ee2cec70ac74168f (patch)
tree54d5586af0a5f7b41de1331168cbdfd5858bd5c7 /sys/netinet6
parent6f0c2ddcfaa3a4664869e1374795f1b1c1f67500 (diff)
downloadFreeBSD-src-600ea5a78241ebe923bc0b42ee2cec70ac74168f.zip
FreeBSD-src-600ea5a78241ebe923bc0b42ee2cec70ac74168f.tar.gz
Add missing locking to udp6_getcred(), remove spl use.
MFC after: 3 months
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/udp6_usrreq.c45
1 files changed, 21 insertions, 24 deletions
diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c
index 65c2be9..d551e17 100644
--- a/sys/netinet6/udp6_usrreq.c
+++ b/sys/netinet6/udp6_usrreq.c
@@ -460,7 +460,7 @@ udp6_getcred(SYSCTL_HANDLER_ARGS)
struct xucred xuc;
struct sockaddr_in6 addrs[2];
struct inpcb *inp;
- int error, s;
+ int error;
error = suser(req->td);
if (error)
@@ -477,19 +477,22 @@ udp6_getcred(SYSCTL_HANDLER_ARGS)
(error = sa6_embedscope(&addrs[1], ip6_use_defzone)) != 0) {
return (error);
}
- s = splnet();
+ INP_INFO_RLOCK(&udbinfo);
inp = in6_pcblookup_hash(&udbinfo, &addrs[1].sin6_addr,
addrs[1].sin6_port,
&addrs[0].sin6_addr, addrs[0].sin6_port,
1, NULL);
- if (!inp || !inp->inp_socket) {
- error = ENOENT;
- goto out;
+ if (inp == NULL) {
+ INP_INFO_RUNLOCK(&udbinfo);
+ return (ENOENT);
}
+ INP_LOCK(inp);
+ KASSERT(inp->inp_socket != NULL,
+ ("udp6_getcred: inp_socket == NULL"));
cru2x(inp->inp_socket->so_cred, &xuc);
+ INP_UNLOCK(inp);
+ INP_INFO_RUNLOCK(&udbinfo);
error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred));
-out:
- splx(s);
return (error);
}
@@ -504,6 +507,7 @@ udp6_abort(struct socket *so)
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("udp6_abort: inp == NULL"));
+
INP_INFO_WLOCK(&udbinfo);
INP_LOCK(inp);
soisdisconnected(so);
@@ -516,19 +520,18 @@ static int
udp6_attach(struct socket *so, int proto, struct thread *td)
{
struct inpcb *inp;
- int s, error;
+ int error;
inp = sotoinpcb(so);
KASSERT(inp == NULL, ("udp6_attach: inp != NULL"));
+
if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
error = soreserve(so, udp_sendspace, udp_recvspace);
if (error)
return error;
}
- s = splnet();
INP_INFO_WLOCK(&udbinfo);
error = in_pcballoc(so, &udbinfo, "udp6inp");
- splx(s);
if (error) {
INP_INFO_WUNLOCK(&udbinfo);
return error;
@@ -556,13 +559,13 @@ static int
udp6_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
{
struct inpcb *inp;
- int s, error;
+ int error;
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("udp6_bind: inp == NULL"));
+
INP_INFO_WLOCK(&udbinfo);
INP_LOCK(inp);
-
inp->inp_vflag &= ~INP_IPV4;
inp->inp_vflag |= INP_IPV6;
if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
@@ -578,19 +581,16 @@ udp6_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
in6_sin6_2_sin(&sin, sin6_p);
inp->inp_vflag |= INP_IPV4;
inp->inp_vflag &= ~INP_IPV6;
- s = splnet();
error = in_pcbbind(inp, (struct sockaddr *)&sin,
td->td_ucred);
goto out;
}
}
- s = splnet();
error = in6_pcbbind(inp, nam, td->td_ucred);
out:
INP_UNLOCK(inp);
INP_INFO_WUNLOCK(&udbinfo);
- splx(s);
return error;
}
@@ -598,10 +598,11 @@ static int
udp6_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
{
struct inpcb *inp;
- int s, error;
+ int error;
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("udp6_connect: inp == NULL"));
+
INP_INFO_WLOCK(&udbinfo);
INP_LOCK(inp);
if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
@@ -614,10 +615,8 @@ udp6_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
if (inp->inp_faddr.s_addr != INADDR_ANY)
return EISCONN;
in6_sin6_2_sin(&sin, sin6_p);
- s = splnet();
error = in_pcbconnect(inp, (struct sockaddr *)&sin,
td->td_ucred);
- splx(s);
if (error == 0) {
inp->inp_vflag |= INP_IPV4;
inp->inp_vflag &= ~INP_IPV6;
@@ -630,9 +629,7 @@ udp6_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
error = EISCONN;
goto out;
}
- s = splnet();
error = in6_pcbconnect(inp, nam, td->td_ucred);
- splx(s);
if (error == 0) {
if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
/* should be non mapped addr */
@@ -654,6 +651,7 @@ udp6_detach(struct socket *so)
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("udp6_detach: inp == NULL"));
+
INP_INFO_WLOCK(&udbinfo);
INP_LOCK(inp);
in6_pcbdetach(inp);
@@ -665,10 +663,11 @@ static int
udp6_disconnect(struct socket *so)
{
struct inpcb *inp;
- int error, s;
+ int error;
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("udp6_disconnect: inp == NULL"));
+
INP_INFO_WLOCK(&udbinfo);
INP_LOCK(inp);
@@ -687,10 +686,8 @@ udp6_disconnect(struct socket *so)
goto out;
}
- s = splnet();
in6_pcbdisconnect(inp);
inp->in6p_laddr = in6addr_any;
- splx(s);
/* XXXRW: so_state locking? */
so->so_state &= ~SS_ISCONNECTED; /* XXX */
out:
@@ -708,9 +705,9 @@ udp6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
inp = sotoinpcb(so);
KASSERT(inp != NULL, ("udp6_send: inp == NULL"));
+
INP_INFO_WLOCK(&udbinfo);
INP_LOCK(inp);
-
if (addr) {
if (addr->sa_len != sizeof(struct sockaddr_in6)) {
error = EINVAL;
OpenPOWER on IntegriCloud