bin/80798: mount_portal pipe leaves file descriptors open for child processes

Jukka A. Ukkonen jau at
Sat Jun 9 08:50:06 UTC 2012

The following reply was made to PR bin/80798; it has been noted by GNATS.

From: "Jukka A. Ukkonen" <jau at>
To: bug-followup at, hohmuth at
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.
 Content-Type: text/plain; charset=ISO-8859-1; format=flowed
 Content-Transfer-Encoding: 7bit
 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
 Notice, though, that the range may be very large. (Ref.
 the resource limits.)
 Content-Type: text/plain; charset=UTF-8;
 Content-Transfer-Encoding: 7bit
 Content-Disposition: attachment;
 --- 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");
 +		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]);

More information about the freebsd-bugs mailing list