From hohmuth@os.inf.tu-dresden.de  Sun May  8 20:15:46 2005
Return-Path: <hohmuth@os.inf.tu-dresden.de>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 3ECF816A4E6
	for <FreeBSD-gnats-submit@freebsd.org>; Sun,  8 May 2005 20:15:46 +0000 (GMT)
Received: from moutng.kundenserver.de (moutng.kundenserver.de [212.227.126.187])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 5FA7F43D2D
	for <FreeBSD-gnats-submit@freebsd.org>; Sun,  8 May 2005 20:15:45 +0000 (GMT)
	(envelope-from hohmuth@os.inf.tu-dresden.de)
Received: from pD9E84120.dip0.t-ipconnect.de[217.232.65.32] (helo=olymp.sax.de)
	by mrelayeu.kundenserver.de with ESMTP (Nemesis),
	id 0ML21M-1DUsBk1ATj-0008NC; Sun, 08 May 2005 22:15:44 +0200
Received: from olymp.sax.de (localhost [127.0.0.1])
	by olymp.sax.de (8.12.9/8.13.3) with ESMTP id j48KHTNv007721
	for <FreeBSD-gnats-submit@freebsd.org>; Sun, 8 May 2005 22:17:29 +0200 (CEST)
	(envelope-from hohmuth@olymp.sax.de)
Received: (from hohmuth@localhost)
	by olymp.sax.de (8.12.9/8.13.1/Submit) id j48KHTTQ007720;
	Sun, 8 May 2005 22:17:29 +0200 (CEST)
	(envelope-from hohmuth)
Message-Id: <200505082017.j48KHTTQ007720@olymp.sax.de>
Date: Sun, 8 May 2005 22:17:29 +0200 (CEST)
From: Michael Hohmuth <hohmuth@sax.de>
Reply-To: Michael Hohmuth <hohmuth@sax.de>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: mount_portal pipe leaves file descriptors open for child processes
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         80798
>Category:       bin
>Synopsis:       mount_portal pipe leaves file descriptors open for child processes
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun May 08 20:20:06 GMT 2005
>Closed-Date:    
>Last-Modified:  Thu Jun 14 06:20:01 UTC 2012
>Originator:     Michael Hohmuth
>Release:        FreeBSD 4.11-STABLE i386
>Organization:
none
>Environment:
System: FreeBSD olymp.sax.de 4.11-STABLE FreeBSD 4.11-STABLE #25: Thu May 5 22:49:15 CEST 2005 root@olymp.sax.de:/usr/obj/usr/src/sys/OLYMP i386

	
>Description:
Commands invoked through the portal file system's "pipe" namespace
inherit some file descriptors from the mount_portal daemon.  This has
two undesirable effects:

1. Files used by mount_portal, including the socket it uses for
   communicating with the kernel part of the portal file system, are
   available to the spawned command.  This could be a security problem.

2. The inactive end of the pipe (stdin for programs whose output is
   read, and stdout for programs that are fed input) is wired to
   /dev/null.  As this is hard or impossible to detect from within the
   program, it is virtually impossible to write programs that can act
   both as the read and the write end of the pipe.  However, this type
   of program is desirable for programs acting as gateways or
   translators.

>How-To-Repeat:
Install a current copy of "lsof", the run the follwing commands (as
any user):

echo 'lsof -p $$' > /tmp/lsof
cat '/p/pipe/bin/sh /tmp/lsof'

You should see something like this:

COMMAND  PID    USER   FD   TYPE     DEVICE SIZE/OFF  NODE NAME
sh      7628 hohmuth  cwd   VDIR 116,196608     1024     2 /
sh      7628 hohmuth  rtd   VDIR 116,196608     1024     2 /
sh      7628 hohmuth  txt   VREG 116,196608   461440 44131 /bin/sh
sh      7628 hohmuth    0u  VCHR        2,2     0t35 21979 /dev/null
sh      7628 hohmuth    1u  PIPE 0xce0222a0    16384       ->0xce0223e0
sh      7628 hohmuth    2u  PIPE 0xce0227a0    16384       ->0xce022020
sh      7628 hohmuth    3r  VREG 116,196608     1070 22651 /etc/fstab
sh      7628 hohmuth    5u  unix 0xcc9bb140      0t0       /tmp/portalILOGROXwic
sh      7628 hohmuth   10r  VREG      253,0       11    56 /tmp/lsof

As you can see, the spawned shell still has /etc/fstab and
/tmp/portalILOGROXwic open (problem 1), and stdin is wired to
/dev/null (problem 2).

>Fix:

To fix problem 1: Close (or do not inherit) all file descriptors >= 3
before execing the child program.

To fix problem 2: Close the child program's stdin when ``reading from
the program,'' or stdout when ``writing to the program,''
respectively.
>Release-Note:
>Audit-Trail:

From: "Jukka A. Ukkonen" <jau@oxit.fi>
To: bug-followup@FreeBSD.org, hohmuth@sax.de
Cc:  
Subject: Re: bin/80798: mount_portal pipe leaves file descriptors open for
 child processes
Date: Sat, 09 Jun 2012 11:49:41 +0300

 This is a multi-part message in MIME format.
 --------------000401050508080706040807
 Content-Type: text/plain; charset=ISO-8859-1; format=flowed
 Content-Transfer-Encoding: 7bit
 
 
 Greetings,
 
 It seems that item 2 is not a real issue, because the unused
 stdin is bound to /dev/null exactly as it should be to avoid
 stdin being accidentally bound to some file while the child
 program is running.
 The same /dev/null treatment works also for stdout to avoid
 accidentally writing to an unexpected file.
 The stderr is directed to a pipe which in turn gets forwarded
 to the syslogd.
 
 While the item 1 has been an anomaly it has not been a big
 issue. The only extra fds left for the child program have been
 a read-only descriptor to /etc/fstab and a writable pipe to
 feed syslogd.
 It seems lsof opens its own new file descriptor under /tmp.
 So, that one does not really count as an anomalous fd.
 
 To be really pedantic about the fds to fstab and syslogd
 apply the attached patch to close everything in the range
 3...(getdtablesize()-1).
 Notice, though, that the range may be very large. (Ref.
 the resource limits.)
 
 --jau
 
 
 --------------000401050508080706040807
 Content-Type: text/plain; charset=UTF-8;
  name="portal_pipe_fds.patch"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: attachment;
  filename="portal_pipe_fds.patch"
 
 --- usr.sbin/mount_portalfs/pt_pipe.c.orig	2012-06-09 10:36:08.000000000 +0300
 +++ usr.sbin/mount_portalfs/pt_pipe.c	2012-06-09 10:52:49.000000000 +0300
 @@ -61,6 +61,11 @@
  	char **argv;
  	int argc;
  	struct portal_cred save_area;
 +	static int maxfds = 0;
 +
 +	if (maxfds == 0) {
 +		maxfds = getdtablesize ();
 +	}
  
  	/* Validate open mode, and assign roles. */
  	if ((pcr->pcr_flag & FWRITE) && (pcr->pcr_flag & FREAD))
 @@ -129,7 +134,22 @@
  			syslog(LOG_ERR, "errlog: %m");
  			exit(EXIT_FAILURE);
  		}
 +
 +		for (i = 3; i < maxfds; i++) {
 +			close (i);
 +		}
 +
  		if (execv(argv[0], argv) < 0) {
 +			/*
 +			 * Start logging _again_ (and change name)
 +			 * because we just closed the descriptor
 +			 * as a side effect of the previous loop
 +			 * while trying to avoid passing extra fds
 +			 * to the child process.
 +			 */
 +
 +			openlog("portald", LOG_CONS|LOG_PID, LOG_DAEMON);
 +
  			syslog(LOG_ERR, "execv(%s): %m", argv[0]);
  			exit(EXIT_FAILURE);
  		}
 
 --------------000401050508080706040807--

From: "Jukka A. Ukkonen" <jau@oxit.fi>
To: bug-followup@FreeBSD.org, hohmuth@sax.de
Cc:  
Subject: Re: bin/80798: mount_portal pipe leaves file descriptors open for
 child processes
Date: Thu, 14 Jun 2012 08:28:45 +0300

 This is a multi-part message in MIME format.
 --------------050707020708060501030604
 Content-Type: text/plain; charset=ISO-8859-1; format=flowed
 Content-Transfer-Encoding: 7bit
 
 
 To properly fix the anomaly (not just a workaround)
 only closing those couple of extra file descriptors at
 exec() apply the attached patch to stop leaking the
 socket to /tmp/portalXXXXXXXXX
 and the patch to the separate PR
 
 http://www.freebsd.org/cgi/query-pr.cgi?pr=bin/80798
 
 which plugs the leak of a descriptor to /etc/fstab.
 
 --jau
 
 
 --------------050707020708060501030604
 Content-Type: text/plain; charset=UTF-8;
  name="mount_portalfs.patch"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: attachment;
  filename="mount_portalfs.patch"
 
 --- usr.sbin/mount_portalfs/mount_portalfs.c.orig	2012-06-14 07:52:20.000000000 +0300
 +++ usr.sbin/mount_portalfs/mount_portalfs.c	2012-06-14 08:07:54.000000000 +0300
 @@ -58,6 +58,7 @@
  #include <string.h>
  #include <sysexits.h>
  #include <unistd.h>
 +#include <fcntl.h>
  
  #include "mntopts.h"
  #include "pathnames.h"
 @@ -167,6 +168,8 @@
  
  	(void) listen(so, 5);
  
 +	(void) fcntl (so, F_SETFD, FD_CLOEXEC);
 +
  	args.pa_socket = so;
  	sprintf(tag, "portal:%d", getpid());
  	args.pa_config = tag;
 @@ -260,6 +263,9 @@
  			break;
  		case 0:
  			(void) close(so);
 +
 +			(void) fcntl (so2, F_SETFD, FD_CLOEXEC);
 +
  			activate(&q, so2);
  			exit(0);
  		default:
 
 --------------050707020708060501030604--

From: "Jukka A. Ukkonen" <jau@oxit.fi>
To: bug-followup@FreeBSD.org, hohmuth@sax.de
Cc:  
Subject: Re: bin/80798: mount_portal pipe leaves file descriptors open for
 child processes
Date: Thu, 14 Jun 2012 08:39:41 +0300

 Oops ...
 The separate PR fixing the fstab leak is actually
 
 http://www.freebsd.org/cgi/query-pr.cgi?pr=misc/169023
 
 

From: Mark Linimon <linimon@lonesome.com>
To: "Jukka A. Ukkonen" <jau@oxit.fi>
Cc: bug-followup@FreeBSD.org
Subject: Re: bin/80798: mount_portal pipe leaves file descriptors open for
 child processes
Date: Thu, 14 Jun 2012 01:12:10 -0500

 On Thu, Jun 14, 2012 at 05:40:05AM +0000, Jukka A. Ukkonen wrote:
 >  The separate PR fixing the fstab leak is actually
 >  
 >  http://www.freebsd.org/cgi/query-pr.cgi?pr=misc/169023
 
 I have reclassified this as kern/169023 and assigned it to freebsd-fs@
 in the hopes of raising its visibility.
 
 mcl
>Unformatted:
