From eugen@grosbein.pp.ru  Sat Apr 24 05:33:45 2004
Return-Path: <eugen@grosbein.pp.ru>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP
	id 9B4B516A4CE; Sat, 24 Apr 2004 05:33:45 -0700 (PDT)
Received: from grosbein.pp.ru (grgw.svzserv.kemerovo.su [213.184.64.130])
	by mx1.FreeBSD.org (Postfix) with ESMTP
	id B81CF43D60; Sat, 24 Apr 2004 05:33:43 -0700 (PDT)
	(envelope-from eugen@grosbein.pp.ru)
Received: from grosbein.pp.ru (eugen@localhost [127.0.0.1])
	by grosbein.pp.ru (8.12.11/8.12.11) with ESMTP id i3OCXdXq001402;
	Sat, 24 Apr 2004 20:33:39 +0800 (KRAST)
	(envelope-from eugen@grosbein.pp.ru)
Received: (from eugen@localhost)
	by grosbein.pp.ru (8.12.11/8.12.11/Submit) id i3OCXctq001401;
	Sat, 24 Apr 2004 20:33:38 +0800 (KRAST)
	(envelope-from eugen)
Message-Id: <200404241233.i3OCXctq001401@grosbein.pp.ru>
Date: Sat, 24 Apr 2004 20:33:38 +0800 (KRAST)
From: Eugene Grosbein <eugen@grosbein.pp.ru>
Reply-To: Eugene Grosbein <eugen@grosbein.pp.ru>
To: FreeBSD-gnats-submit@freebsd.org
Cc: yar@freebsd.org
Subject: [PATCH] stock ftpd uses superuser credentials for active mode sockets
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         65928
>Category:       bin
>Synopsis:       [PATCH] stock ftpd uses superuser credentials for active mode sockets
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    yar
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Apr 24 05:40:07 PDT 2004
>Closed-Date:    Sat Aug 28 13:21:28 GMT 2004
>Last-Modified:  Sat Aug 28 13:21:28 GMT 2004
>Originator:     Eugene Grosbein
>Release:        FreeBSD 4.10-BETA i386
>Organization:
Svyaz Service JSC
>Environment:
System: FreeBSD grosbein.pp.ru 4.10-BETA FreeBSD 4.10-BETA #0: Sun Apr 11 15:43:04 KRAST 2004 eu@grosbein.pp.ru:/usr/local/obj/usr/local/src/sys/DADV i386

>Description:
		ftpd(8) has to switch euid to 0 when it needs to bind(2)
		a socket to a port 'ftp-data' for active mode transfer.
		Now uses seteuid/socket/bind/... sequence. So the socket
		belongs to the superuser and data flow is matched
		by rules similar to:

		ipfw add count tcp from me 20 to any uid root

		The sequence socket/seteuid/bind results in another situation:
		the socket belongs to the authenticated user and
		data flow is matched by rules similar to:

		ipfw add count tcp from me 20 to any uid ftp

		That's much better. That makes it possible to engage
		all the power of system credential control.
		Ftp traffic can be shaped using dummynet per-user,
		for example. It can be easily accounted or blocked, too.
		The same for ordinary user's traffic.
		
>How-To-Repeat:

		Use rules like this:

ipfw add 1 count tcp from 127.0.0.1 ftp-data to any uid root out
ipfw add 2 count tcp from 127.0.0.1 ftp-data to any uid ftp out

		Connect to local ftpd, turn passive mode off and do 'ls'.
		Then see ipfw rules counters.

>Fix:

		Apply next patch:

--- ftpd.c.orig	Fri Apr 23 20:42:47 2004
+++ ftpd.c	Fri Apr 23 20:43:23 2004
@@ -1792,7 +1792,6 @@
 
 	if (data >= 0)
 		return (fdopen(data, mode));
-	(void) seteuid((uid_t)0);
 
 	s = socket(data_dest.su_family, SOCK_STREAM, 0);
 	if (s < 0)
@@ -1802,6 +1801,7 @@
 	/* anchor socket to avoid multi-homing problems */
 	data_source = ctrl_addr;
 	data_source.su_port = htons(dataport);
+	(void) seteuid((uid_t)0);
 	for (tries = 1; ; tries++) {
 		if (bind(s, (struct sockaddr *)&data_source,
 		    data_source.su_len) >= 0)


Eugene Grosbein
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->yar 
Responsible-Changed-By: yar 
Responsible-Changed-When: Tue Apr 27 02:48:58 PDT 2004 
Responsible-Changed-Why:  
I've tested the solution proposed and I'm about to commit it RSN. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=65928 

From: Yar Tikhiy <yar@FreeBSD.org>
To: freebsd-gnats-submit@FreeBSD.org, eugen@grosbein.pp.ru
Cc:  
Subject: Re: bin/65928: [PATCH] stock ftpd uses superuser credentials for active mode sockets
Date: Fri, 7 May 2004 09:48:22 +0400

 While the solution looks clear and nice, a problem seems to lurk
 behind it.  It arises from a security feature of modern Berkeley
 sockets API implementations found in *BSD (and maybe in Linux, too.)
 Namely, an unprivileged process (euid != 0) may not bind a socket
 to a local IP:port couple already occupied by another uid.  This
 restriction is triggered when a socket from another uid is already
 bound to the local IP:port couple in question or to the wildcard
 *:port couple.
 
 Now let's see how the above affects this ftpd(8) case.  Unpatched
 ftpd(8) makes an active mode data socket belong to uid 0.  Such a
 socket may bind to any local IP:port couple unless it is actually
 in use.  After the patch applied, an active mode data socket will
 belong to the user ftpd(8) is running on behalf of, be it "ftp" or
 a real local account.  As long as it is the only user ftpd(8) runs
 from on this IP, no problem will be seen because all the active
 mode data sockets belong to the same uid.  Now let's consider what
 will happen if another user connects to ftpd(8) on this IP while the
 former user is transferring data through an active mode data connection.
 The very first attempt by the latter user to open an active mode data
 connection will fail with EADDRINUSE because there already exists
 another active mode data socket bound to the same IP:port couple but
 belonging to a different uid.
 
 The way to reproduce the problem is straightforward.  Log in to the
 patched ftpd as a local user and start a lenghthy transfer in active
 mode.  Than log in again as another local user (make sure you're
 connected to the same IP!) and start any transfer in active mode--
 issuing "ls" will be enough.  You'll get a error "Address already
 in use" after some delay when the latter ftp client instance tries
 to open a data connection.
 
 What puzzles me is whether it is indeed neccessary to consider
 sockets (in detail, inpcb's) already connected to a particular
 remote IP:port couple when applying the bind() restriction.
 Now as little as having an open connection to some remote service
 from a local IP:port couple will prevent other users (except the
 superuser) from reusing that IP:port.
 
 -- 
 Yar

From: "Nick Leuta" <skynick@mail.sc.ru>
To: <freebsd-gnats-submit@FreeBSD.org>, <eugen@grosbein.pp.ru>
Cc:  
Subject: Re: bin/65928: [PATCH] stock ftpd uses superuser credentials for active mode sockets
Date: Sat, 8 May 2004 18:16:01 +0400

 I'm about "and maybe in Linux, too" sentence: in Linux (at least in 2.4.20
 kernel) there are NO described problem, and "fuser" utility shows that both
 sockets (two simultaneous downloads from the same IP address in active mode)
 are used by the processes owned by root.
 
 So this problem seems to be specific for *BSD systems.
 
 =======
 SkyNick
 

From: Nick Leuta <skynick@mail.sc.ru>
To: freebsd-gnats-submit@FreeBSD.org, eugen@grosbein.pp.ru
Cc:  
Subject: Re: bin/65928: [PATCH] stock ftpd uses superuser credentials for active mode sockets
Date: Mon, 10 May 2004 02:56:28 +0400

 Moreover, i can't reproduce the problem with my 4 days old
 5.2-CURRENT (GENERIC): two simultaneous downloads from/to 127.0.0.1 in active
 mode (of course, with the patched ftpd and the real (uid!=0) user) go without
 any problems...
 
 Is it possible that the more detailed list of conditions is required to
 reproduce the problem?
 
 -- 
 SkyNick

From: Nick Leuta <skynick@mail.sc.ru>
To: freebsd-gnats-submit@FreeBSD.org, eugen@grosbein.pp.ru
Cc:  
Subject: Re: bin/65928: [PATCH] stock ftpd uses superuser credentials for active mode sockets
Date: Mon, 10 May 2004 03:52:47 +0400

 I'm sorry - different users must have different uids, not only names, eh? :-))
 
 But i'm still to be sure about Linux (as noted earlier).
 
 -- 
 SkyNick
State-Changed-From-To: open->analyzed 
State-Changed-By: yar 
State-Changed-When: Tue May 11 08:45:16 PDT 2004 
State-Changed-Why:  
The problem and its implication have been outlined. 
I hope we'll do something with the TCP/IP issue soon 
enough for this PR to not slip into the suspended state :-) 

http://www.freebsd.org/cgi/query-pr.cgi?pr=65928 

From: Yar Tikhiy <yar@comp.chem.msu.su>
To: freebsd-gnats-submit@FreeBSD.org, eugen@grosbein.pp.ru
Cc:  
Subject: Re: bin/65928: [PATCH] stock ftpd uses superuser credentials for active mode sockets
Date: Wed, 28 Jul 2004 12:46:26 +0400

 Progress report:
 
 Since I committed a fix for the IPv6 bind(2) as well yesterday,
 we've got the green light to make the change to ftpd(8).  I'll do
 this in a few days if no problems with my changes to the IP stack
 arise.  (There sould be none.)
 
 -- 
 Yar
State-Changed-From-To: analyzed->patched 
State-Changed-By: yar 
State-Changed-When: Mon Aug 2 12:16:56 GMT 2004 
State-Changed-Why:  
The proposed change has been introduced to CURRENT, thanks! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=65928 
State-Changed-From-To: patched->closed 
State-Changed-By: yar 
State-Changed-When: Sat Aug 28 13:19:51 GMT 2004 
State-Changed-Why:  
The problem has been eliminated.  Thanks! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=65928 
>Unformatted:
