Date: Sun, 18 May 1997 15:08:52 +0200 (CEST) From: Tor Egge <Tor.Egge@idt.ntnu.no> To: FreeBSD-gnats-submit@FreeBSD.ORG Subject: kern/3618: getsockname and getpeername may cause trap 12 Message-ID: <199705181308.PAA00589@skarven.itea.ntnu.no> Resent-Message-ID: <199705181310.GAA27617@hub.freebsd.org>
index | next in thread | raw e-mail
>Number: 3618
>Category: kern
>Synopsis: getsockname and getpeername may cause trap 12
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Sun May 18 06:10:02 PDT 1997
>Last-Modified:
>Originator: Tor Egge
>Organization:
Norwegian University of Science and Technology, Trondheim, Norway
>Release: FreeBSD 3.0-CURRENT i386
>Environment:
FreeBSD skarven.itea.ntnu.no 3.0-CURRENT FreeBSD 3.0-CURRENT #1: Sun May 18 14:41:28 CEST 1997 root@skarven.itea.ntnu.no:/usr/src/sys/compile/SKARVEN i386
>Description:
During the getsockname() or getpeername() call, a network interrupt
might reset the connection, causing the socket to no longer have a pcb.
If this happens at the wrong time, the system gets a trap 12.
>How-To-Repeat:
Run an FTP server with tcp wrappers installed on the system.
Start a lot of connections to the ftp server, and close/reset
the connections from the client side as soon as the connection is established.
>Fix:
Disallow network interrupts while the address is found and copied.
Handle the case where the socket was disconnected before the network
interrupts were disabled.
Index: in_pcb.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/in_pcb.c,v
retrieving revision 1.31
diff -c -r1.31 in_pcb.c
*** in_pcb.c 1997/04/27 20:01:04 1.31
--- in_pcb.c 1997/05/18 12:50:35
***************
*** 470,478 ****
--- 470,483 ----
struct socket *so;
struct mbuf *nam;
{
+ int s = splnet();
register struct inpcb *inp = sotoinpcb(so);
register struct sockaddr_in *sin;
+ if (!inp) {
+ splx(s);
+ return EINVAL;
+ }
nam->m_len = sizeof (*sin);
sin = mtod(nam, struct sockaddr_in *);
bzero((caddr_t)sin, sizeof (*sin));
***************
*** 480,485 ****
--- 485,491 ----
sin->sin_len = sizeof(*sin);
sin->sin_port = inp->inp_lport;
sin->sin_addr = inp->inp_laddr;
+ splx(s);
return 0;
}
***************
*** 488,496 ****
--- 494,507 ----
struct socket *so;
struct mbuf *nam;
{
+ int s = splnet();
struct inpcb *inp = sotoinpcb(so);
register struct sockaddr_in *sin;
+ if (!inp) {
+ splx(s);
+ return EINVAL;
+ }
nam->m_len = sizeof (*sin);
sin = mtod(nam, struct sockaddr_in *);
bzero((caddr_t)sin, sizeof (*sin));
***************
*** 498,503 ****
--- 509,515 ----
sin->sin_len = sizeof(*sin);
sin->sin_port = inp->inp_fport;
sin->sin_addr = inp->inp_faddr;
+ splx(s);
return 0;
}
>Audit-Trail:
>Unformatted:
home |
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199705181308.PAA00589>
