summaryrefslogtreecommitdiffstats
path: root/sys/netnatm
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2006-04-23 16:04:07 +0000
committerrwatson <rwatson@FreeBSD.org>2006-04-23 16:04:07 +0000
commit8f33c5d4671279b7fb7558b4766a1d7d5dbdee8c (patch)
tree81c7cd671f1ff42de70f267b4d47c085a7cbc578 /sys/netnatm
parent426844655f72c3977d8e833a3aa122b87ce7faef (diff)
downloadFreeBSD-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
Diffstat (limited to 'sys/netnatm')
-rw-r--r--sys/netnatm/natm.c12
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);
OpenPOWER on IntegriCloud