From 92d8381dd544a8237b3fd68c4e7fce9bd0903fb2 Mon Sep 17 00:00:00 2001 From: tanimura Date: Mon, 20 May 2002 05:41:09 +0000 Subject: Lock down a socket, milestone 1. o Add a mutex (sb_mtx) to struct sockbuf. This protects the data in a socket buffer. The mutex in the receive buffer also protects the data in struct socket. o Determine the lock strategy for each members in struct socket. o Lock down the following members: - so_count - so_options - so_linger - so_state o Remove *_locked() socket APIs. Make the following socket APIs touching the members above now require a locked socket: - sodisconnect() - soisconnected() - soisconnecting() - soisdisconnected() - soisdisconnecting() - sofree() - soref() - sorele() - sorwakeup() - sotryfree() - sowakeup() - sowwakeup() Reviewed by: alfred --- sys/security/lomac/kernel_interface.c | 11 +++++-- sys/security/lomac/kernel_socket.c | 62 +++++++++++++++++++++++++++-------- 2 files changed, 57 insertions(+), 16 deletions(-) (limited to 'sys/security') diff --git a/sys/security/lomac/kernel_interface.c b/sys/security/lomac/kernel_interface.c index adaff99..9093ff3 100644 --- a/sys/security/lomac/kernel_interface.c +++ b/sys/security/lomac/kernel_interface.c @@ -413,10 +413,15 @@ set_object_lattr(lomac_object_t *obj, lattr_t lattr) { case LO_TYPE_SOCKETPAIR: socket = obj->lo_object.socket; /* KASSERT that socket peer levels are synchronized */ - if (lattr.level == LOMAC_HIGHEST_LEVEL) + if (lattr.level == LOMAC_HIGHEST_LEVEL) { + SOCK_LOCK(socket); socket->so_state &= ~SOCKET_LEVEL_LOWEST; - else + SOCK_UNLOCK(socket); + } else { + SOCK_LOCK(socket); socket->so_state |= SOCKET_LEVEL_LOWEST; + SOCK_UNLOCK(socket); + } #ifdef NOT_YET pipe = pipe->pipe_peer; if (pipe != NULL) { @@ -474,8 +479,10 @@ get_object_lattr(const lomac_object_t *obj, lattr_t *lattr) { break; case LO_TYPE_SOCKETPAIR: socket = obj->lo_object.socket; + SOCK_LOCK(socket); lattr->level = (socket->so_state & SOCKET_LEVEL_LOWEST) ? LOMAC_LOWEST_LEVEL : LOMAC_HIGHEST_LEVEL; + SOCK_UNLOCK(socket); lattr->flags = 0; break; default: diff --git a/sys/security/lomac/kernel_socket.c b/sys/security/lomac/kernel_socket.c index 291ccc2..0c62f32 100644 --- a/sys/security/lomac/kernel_socket.c +++ b/sys/security/lomac/kernel_socket.c @@ -245,8 +245,14 @@ lomac_local_connect(struct socket *so, struct sockaddr *nam, struct thread *td) goto bad; } if (so->so_proto->pr_flags & PR_CONNREQUIRED) { - if ((so2->so_options & SO_ACCEPTCONN) == 0 || - (so3 = sonewconn(so2, 0)) == 0) { + SOCK_LOCK(so2); + if ((so2->so_options & SO_ACCEPTCONN) == 0) { + SOCK_UNLOCK(so2); + error = ECONNREFUSED; + goto bad; + } + SOCK_UNLOCK(so2); + if ((so3 = sonewconn(so2, 0)) == 0) { error = ECONNREFUSED; goto bad; } @@ -345,15 +351,20 @@ lomac_local_send( struct socket *so, int flags, struct mbuf *m, error = ENOTCONN; goto out; } - } else if ((so->so_state & SS_ISCONNECTED) == 0) { - if (addr != NULL) { - error = lomac_local_connect(so, addr, td); - if (error) - goto out; /* XXX */ - } else { - error = ENOTCONN; - goto out; - } + } else { + SOCK_LOCK(so); + if ((so->so_state & SS_ISCONNECTED) == 0) { + SOCK_UNLOCK(so); + if (addr != NULL) { + error = lomac_local_connect(so, addr, td); + if (error) + goto out; /* XXX */ + } else { + error = ENOTCONN; + goto out; + } + } else + SOCK_UNLOCK(so); } vp = unp->unp_vnode; if (vp != NULL) { @@ -560,8 +571,12 @@ bad: } if (mp) *mp = (struct mbuf *)0; - if (so->so_state & SS_ISCONFIRMING && uio->uio_resid) + SOCK_LOCK(so); + if (so->so_state & SS_ISCONFIRMING && uio->uio_resid) { + SOCK_UNLOCK(so); (*pr->pr_usrreqs->pru_rcvd)(so, 0); + } else + SOCK_UNLOCK(so); restart: error = sblock(&so->so_rcv, SBLOCKWAIT(flags)); @@ -597,7 +612,9 @@ restart: so->so_error = 0; goto release; } + SOCK_LOCK(so); if (so->so_state & SS_CANTRCVMORE) { + SOCK_UNLOCK(so); if (m) goto dontblock; else @@ -606,19 +623,25 @@ restart: for (; m; m = m->m_next) if (m->m_type == MT_OOBDATA || (m->m_flags & M_EOR)) { m = so->so_rcv.sb_mb; + SOCK_UNLOCK(so); goto dontblock; } if ((so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) == 0 && (so->so_proto->pr_flags & PR_CONNREQUIRED)) { + SOCK_UNLOCK(so); error = ENOTCONN; goto release; } - if (uio->uio_resid == 0) + if (uio->uio_resid == 0) { + SOCK_UNLOCK(so); goto release; + } if ((so->so_state & SS_NBIO) || (flags & MSG_DONTWAIT)) { + SOCK_UNLOCK(so); error = EWOULDBLOCK; goto release; } + SOCK_LOCK(so); sbunlock(&so->so_rcv); error = sbwait(&so->so_rcv); splx(s); @@ -687,7 +710,9 @@ dontblock: else KASSERT(m->m_type == MT_DATA || m->m_type == MT_HEADER, ("receive 3")); + SOCK_LOCK(so); so->so_state &= ~SS_RCVATMARK; + SOCK_UNLOCK(so); len = uio->uio_resid; if (so->so_oobmark && len > so->so_oobmark - offset) len = so->so_oobmark - offset; @@ -746,7 +771,9 @@ dontblock: if ((flags & MSG_PEEK) == 0) { so->so_oobmark -= len; if (so->so_oobmark == 0) { + SOCK_LOCK(so); so->so_state |= SS_RCVATMARK; + SOCK_UNLOCK(so); break; } } else { @@ -766,8 +793,12 @@ dontblock: */ while (flags & MSG_WAITALL && m == 0 && uio->uio_resid > 0 && !sosendallatonce(so) && !nextrecord) { - if (so->so_error || so->so_state & SS_CANTRCVMORE) + SOCK_LOCK(so); + if (so->so_error || so->so_state & SS_CANTRCVMORE) { + SOCK_UNLOCK(so); break; + } + SOCK_UNLOCK(so); /* * Notify the protocol that some data has been * drained before blocking. @@ -797,12 +828,15 @@ dontblock: if (pr->pr_flags & PR_WANTRCVD && so->so_pcb) (*pr->pr_usrreqs->pru_rcvd)(so, flags); } + SOCK_LOCK(so); if (orig_resid == uio->uio_resid && orig_resid && (flags & MSG_EOR) == 0 && (so->so_state & SS_CANTRCVMORE) == 0) { + SOCK_UNLOCK(so); sbunlock(&so->so_rcv); splx(s); goto restart; } + SOCK_UNLOCK(so); if (flagsp) *flagsp |= flags; -- cgit v1.1