diff options
author | rwatson <rwatson@FreeBSD.org> | 2006-04-23 16:04:07 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2006-04-23 16:04:07 +0000 |
commit | 8f33c5d4671279b7fb7558b4766a1d7d5dbdee8c (patch) | |
tree | 81c7cd671f1ff42de70f267b4d47c085a7cbc578 | |
parent | 426844655f72c3977d8e833a3aa122b87ce7faef (diff) | |
download | FreeBSD-src-8f33c5d4671279b7fb7558b4766a1d7d5dbdee8c.zip FreeBSD-src-8f33c5d4671279b7fb7558b4766a1d7d5dbdee8c.tar.gz |
Acquire natm mutex after traversing so_pcb, not before, as the protocol
mutex is no longer required to ensure that so_pcb is valid.
Make sure to free (control) in natm_usr_send() when there M_PREPEND()
frees (m).
MFC after: 3 months
-rw-r--r-- | sys/netnatm/natm.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/sys/netnatm/natm.c b/sys/netnatm/natm.c index 95f9368..1f43a4a 100644 --- a/sys/netnatm/natm.c +++ b/sys/netnatm/natm.c @@ -116,9 +116,10 @@ natm_usr_detach(struct socket *so) { struct natmpcb *npcb; - NATM_LOCK(); npcb = (struct natmpcb *)so->so_pcb; KASSERT(npcb != NULL, ("natm_usr_detach: npcb == NULL")); + + NATM_LOCK(); npcb_free(npcb, NPCB_DESTROY); /* drain */ so->so_pcb = NULL; NATM_UNLOCK(); @@ -134,13 +135,13 @@ natm_usr_connect(struct socket *so, struct sockaddr *nam, d_thread_t *p) int error = 0; int proto = so->so_proto->pr_protocol; - NATM_LOCK(); npcb = (struct natmpcb *)so->so_pcb; KASSERT(npcb != NULL, ("natm_usr_connect: npcb == NULL")); /* * validate nam and npcb */ + NATM_LOCK(); snatm = (struct sockaddr_natm *)nam; if (snatm->snatm_len != sizeof(*snatm) || (npcb->npcb_flags & NPCB_FREE) == 0) { @@ -212,10 +213,10 @@ natm_usr_disconnect(struct socket *so) struct ifnet *ifp; int error = 0; - NATM_LOCK(); npcb = (struct natmpcb *)so->so_pcb; KASSERT(npcb != NULL, ("natm_usr_disconnect: npcb == NULL")); + NATM_LOCK(); if ((npcb->npcb_flags & NPCB_CONNECTED) == 0) { printf("natm: disconnected check\n"); error = EIO; @@ -259,10 +260,10 @@ natm_usr_send(struct socket *so, int flags, struct mbuf *m, int error = 0; int proto = so->so_proto->pr_protocol; - NATM_LOCK(); npcb = (struct natmpcb *)so->so_pcb; KASSERT(npcb != NULL, ("natm_usr_send: npcb == NULL")); + NATM_LOCK(); if (control && control->m_len) { m_freem(control); m_freem(m); @@ -275,6 +276,7 @@ natm_usr_send(struct socket *so, int flags, struct mbuf *m, */ M_PREPEND(m, sizeof(*aph), M_DONTWAIT); if (m == NULL) { + m_freem(control); error = ENOBUFS; goto out; } @@ -296,10 +298,10 @@ natm_usr_peeraddr(struct socket *so, struct sockaddr **nam) struct natmpcb *npcb; struct sockaddr_natm *snatm, ssnatm; - NATM_LOCK(); npcb = (struct natmpcb *)so->so_pcb; KASSERT(npcb != NULL, ("natm_usr_peeraddr: npcb == NULL")); + NATM_LOCK(); snatm = &ssnatm; bzero(snatm, sizeof(*snatm)); snatm->snatm_len = sizeof(*snatm); |