From kattyo@abk.nu  Sat Mar 18 22:06:52 2000
Return-Path: <kattyo@abk.nu>
Received: from cl2.nit.ac.jp (cl2.nit.ac.jp [202.18.170.10])
	by hub.freebsd.org (Postfix) with ESMTP id 86B4F37B6A0
	for <FreeBSD-gnats-submit@freebsd.org>; Sat, 18 Mar 2000 22:06:49 -0800 (PST)
	(envelope-from kattyo@abk.nu)
Received: (from uucp@localhost)
	by cl2.nit.ac.jp (8.9.3/3.7W-99110818) id PAA26957
	for <FreeBSD-gnats-submit@freebsd.org>; Sun, 19 Mar 2000 15:05:15 +0900 (JST)
Received: from uhura.nit.ac.jp(202.18.172.80) by cl2.nit.ac.jp via smap (V4.2)
	id xma026933; Sun, 19 Mar 00 15:05:12 +0900
Received: from myhost ([192.168.0.206]) by uhura.nit.ac.jp (8.7.1+2.6Wbeta4/3.4Wbeta6) with SMTP id PAA09459 for FreeBSD-gnats-submit@freebsd.org; Sun, 19 Mar 2000 15:06:29 +0900 (JST)
Message-Id: <200003190606.PAA09459@uhura.nit.ac.jp>
Date: Sun, 19 Mar 2000 15:06:29 +0900 (JST)
From: Kattyo <kattyo@abk.nu>
Reply-To: TANAKA Hiroyuki <kattyo@abk.nu>,
	Takahiro Kambe <taca@sky.yamashina.kyoto.jp>
To: FreeBSD-gnats-submit@freebsd.org
Subject: ftpd not close listening port when failed data xfer in passive mode
X-Send-Pr-Version: 3.2

>Number:         17482
>Category:       bin
>Synopsis:       ftpd(8) forget to close TCP port in passive mode
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Mar 18 22:10:01 PST 2000
>Closed-Date:    Sat Jul 21 17:47:03 PDT 2001
>Last-Modified:  Sat Jul 21 17:47:42 PDT 2001
>Originator:     TANAKA Hiroyuki
>Release:        FreeBSD 3.2-RELEASE i386
>Organization:
Nippon Institute of Technology
>Environment:

	FreeBSD 3.2R and /usr/libexec/ftpd

>Description:

	When ftpd fail data transfer with reply code 55x in passive mode,
	ftpd forget to close socket which listening for data transfer.
	
	This problem will affect anonymous ftp server as security hole.
	(Can do DoS attack.)

>How-To-Repeat:

	% ftp -p localhost
	Connected localhost.
	-- snip -- (here login) --
	ftp> get no-such-filename
	227 Entering Passive Mode (127,0,0,1,123,45)
	550 no-such-filename: No such a file or directory.
	ftp> !netstat -f inet
	Proto Send-Q Recv-Q  Local Address       Foreign Address  State
	tcp        0      0  localhost.31533     *.*              LISTEN
	tcp        0      0  localhost.ftp       localhost.31531  ESTABLISHED
	ftp> get no-such-filename
	227 Entering Passive Mode (127,0,0,1,123,46)
	550 no-such-filename: No such a file or directory.
	ftp> !netstat -f inet
	Proto Send-Q Recv-Q  Local Address       Foreign Address  State
	tcp        0      0  localhost.31533     *.*              LISTEN
	tcp        0      0  localhost.31534     *.*              LISTEN
	tcp        0      0  localhost.ftp       localhost.31531  ESTABLISHED


	If more and more retry it, to be out of file descripter and
	many commands can't execute because cant't load dynamic link libraries.


	total problem points:

	1.	PASV
		NLST (at empty directory)
	2.	PASV
		RETR no-such-filename
	3.	PASV
		STOR no-writable-filename
	     or	APPE no-writable-filename
	     or	STOU in-no-writable-directory


>Fix:

This patch is not perfect.


*** old/ftpd.c	Sun Mar 19 02:26:11 2000
--- ftpd.c	Sun Mar 19 14:23:45 2000
***************
*** 1156,1161 ****
--- 1156,1165 ----
  			if (cmd == 0) {
  				LOGCMD("get", name);
  			}
+ 			if (pdata >= 1) {
+ 				(void) close(pdata);
+ 				pdata = -1;
+ 			}
  		}
  		return;
  	}
***************
*** 1194,1201 ****
  		logxfer(name, st.st_size, start);
  	(void) fclose(dout);
  	data = -1;
- 	pdata = -1;
  done:
  	if (cmd == 0)
  		LOGBYTES("get", name, byte_count);
  	(*closefunc)(fin);
--- 1198,1208 ----
  		logxfer(name, st.st_size, start);
  	(void) fclose(dout);
  	data = -1;
  done:
+ 	if (pdata >= 0) {
+ 		(void) close(pdata);
+ 	}
+ 	pdata = -1;
  	if (cmd == 0)
  		LOGBYTES("get", name, byte_count);
  	(*closefunc)(fin);
***************
*** 2219,2224 ****
--- 2226,2235 ----
  	transflag = 0;
  	if (dout != NULL)
  		(void) fclose(dout);
+ 	else {
+ 		if (pdata >= 0)
+ 			(void) close(pdata);
+ 	}
  	data = -1;
 	pdata = -1;
  out:


>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed 
State-Changed-By: mike 
State-Changed-When: Sat Jul 21 17:47:03 PDT 2001 
State-Changed-Why:  

It appears this problem is solved.  I can't reproduce this on 
5.0-CURRENT. 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=17482 
>Unformatted:
