Skip site navigation (1)Skip section navigation (2)
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>

next in thread | raw e-mail | index | archive | help

>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:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199705181308.PAA00589>