diff options
author | dg <dg@FreeBSD.org> | 1997-12-25 06:57:36 +0000 |
---|---|---|
committer | dg <dg@FreeBSD.org> | 1997-12-25 06:57:36 +0000 |
commit | 2a494c06e20d05a6406bbc5cf486fc7a7439286b (patch) | |
tree | d90fce962eaa645000eecc3da221455c99526779 /sys/netinet/in_pcb.c | |
parent | 13a5c596cc1e305e6ce6704550ee7543707116c1 (diff) | |
download | FreeBSD-src-2a494c06e20d05a6406bbc5cf486fc7a7439286b.zip FreeBSD-src-2a494c06e20d05a6406bbc5cf486fc7a7439286b.tar.gz |
The spl fixes in in_setsockaddr and in_setpeeraddr that were meant to
fix PR#3618 weren't sufficient since malloc() can block - allowing the
net interrupts in and leading to the same problem mentioned in the
PR (a panic). The order of operations has been changed so that this
is no longer a problem.
Needs to be brought into the 2.2.x branch.
PR: 3618
Diffstat (limited to 'sys/netinet/in_pcb.c')
-rw-r--r-- | sys/netinet/in_pcb.c | 28 |
1 files changed, 17 insertions, 11 deletions
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 5a46709..e9a83d3 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)in_pcb.c 8.4 (Berkeley) 5/24/95 - * $Id: in_pcb.c,v 1.35 1997/10/28 15:58:42 bde Exp $ + * $Id: in_pcb.c,v 1.36 1997/12/23 01:40:40 alex Exp $ */ #include <sys/param.h> @@ -470,20 +470,23 @@ in_setsockaddr(so, nam) register struct inpcb *inp; register struct sockaddr_in *sin; + MALLOC(sin, struct sockaddr_in *, sizeof *sin, M_SONAME, M_WAITOK); + bzero(sin, sizeof *sin); + sin->sin_family = AF_INET; + sin->sin_len = sizeof(*sin); + s = splnet(); inp = sotoinpcb(so); if (!inp) { splx(s); + free(sin, M_SONAME); return EINVAL; } - MALLOC(sin, struct sockaddr_in *, sizeof *sin, M_SONAME, M_WAITOK); - *nam = (struct sockaddr *)sin; - bzero(sin, sizeof *sin); - sin->sin_family = AF_INET; - sin->sin_len = sizeof(*sin); sin->sin_port = inp->inp_lport; sin->sin_addr = inp->inp_laddr; splx(s); + + *nam = (struct sockaddr *)sin; return 0; } @@ -496,20 +499,23 @@ in_setpeeraddr(so, nam) struct inpcb *inp; register struct sockaddr_in *sin; + MALLOC(sin, struct sockaddr_in *, sizeof *sin, M_SONAME, M_WAITOK); + bzero((caddr_t)sin, sizeof (*sin)); + sin->sin_family = AF_INET; + sin->sin_len = sizeof(*sin); + s = splnet(); inp = sotoinpcb(so); if (!inp) { splx(s); + free(sin, M_SONAME); return EINVAL; } - MALLOC(sin, struct sockaddr_in *, sizeof *sin, M_SONAME, M_WAITOK); - *nam = (struct sockaddr *)sin; - bzero((caddr_t)sin, sizeof (*sin)); - sin->sin_family = AF_INET; - sin->sin_len = sizeof(*sin); sin->sin_port = inp->inp_fport; sin->sin_addr = inp->inp_faddr; splx(s); + + *nam = (struct sockaddr *)sin; return 0; } |