From nobody@FreeBSD.org  Wed Jun 13 07:03:07 2012
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (unknown [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 37407106566B
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 13 Jun 2012 07:03:07 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from red.freebsd.org (red.freebsd.org [69.147.83.34])
	by mx1.freebsd.org (Postfix) with ESMTP id 22E088FC16
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 13 Jun 2012 07:03:07 +0000 (UTC)
Received: from red.freebsd.org (localhost [127.0.0.1])
	by red.freebsd.org (8.14.4/8.14.4) with ESMTP id q5D736xL010010
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 13 Jun 2012 07:03:06 GMT
	(envelope-from nobody@red.freebsd.org)
Received: (from nobody@localhost)
	by red.freebsd.org (8.14.4/8.14.4/Submit) id q5D736Vd010009;
	Wed, 13 Jun 2012 07:03:06 GMT
	(envelope-from nobody)
Message-Id: <201206130703.q5D736Vd010009@red.freebsd.org>
Date: Wed, 13 Jun 2012 07:03:06 GMT
From: Jukka Ukkonen <jau@iki.fi>
To: freebsd-gnats-submit@FreeBSD.org
Subject: setfsent(), getfsent(), etc. leave /etc/fstab open after exec()
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         169023
>Category:       kern
>Synopsis:       [libc] [patch] setfsent(), getfsent(), etc. leave /etc/fstab open after exec()
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    kib
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jun 13 07:10:09 UTC 2012
>Closed-Date:    Thu Jun 21 08:55:51 UTC 2012
>Last-Modified:  Thu Jun 21 09:00:20 UTC 2012
>Originator:     Jukka Ukkonen
>Release:        FreeBSD 9.0-STABLE
>Organization:
----
>Environment:
FreeBSD sleipnir 9.0-STABLE FreeBSD 9.0-STABLE #0: Wed Jun 13 08:47:09 EEST 2012     root@sleipnir:/usr/obj/usr/src/sys/Sleipnir  amd64
>Description:
setfstab() causes a file descriptor being left open to /etc/fstab after exec(),
because it does not properly set FD_CLOEXEC.

This was categorized as "misc" because there is no category "lib"/"libraries".

>How-To-Repeat:
See e.g.
http://www.freebsd.org/cgi/query-pr.cgi?pr=bin/80798
>Fix:
Apply the attached patch ASAP.
This anomaly has been around for years, at least since 2005.


Patch attached with submission follows:

--- lib/libc/gen/fstab.c.orig	2012-06-10 13:54:38.000000000 +0300
+++ lib/libc/gen/fstab.c	2012-06-10 13:58:53.000000000 +0300
@@ -45,6 +45,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <fcntl.h>
 #include "un-namespace.h"
 
 static FILE *_fs_fp;
@@ -58,6 +59,8 @@
 static void fixfsfile(void);
 static int fstabscan(void);
 
+extern int     fcntl(int, int, ...);
+
 void
 setfstab(const char *file)
 {
@@ -258,6 +261,11 @@
 			setfstab(getenv("PATH_FSTAB"));
 	}
 	if ((_fs_fp = fopen(path_fstab, "r")) != NULL) {
+		int	fd;
+
+		fd = fileno (_fs_fp);
+		fcntl (fd, F_SETFD, FD_CLOEXEC);
+
 		LineNo = 0;
 		return(1);
 	}


>Release-Note:
>Audit-Trail:

From: "Jukka A. Ukkonen" <jau@oxit.fi>
To: bug-followup@FreeBSD.org, jau@iki.fi
Cc:  
Subject: Re: misc/169023: setfsent(), getfsent(), etc. leave /etc/fstab open
 after exec()
Date: Thu, 14 Jun 2012 08:34:06 +0300

 This is a multi-part message in MIME format.
 --------------090001050406070603010704
 Content-Type: text/plain; charset=ISO-8859-1; format=flowed
 Content-Transfer-Encoding: 7bit
 
 A better version of the same patch which now uses _fcntl() instead of 
 plain fcntl().
 
 
 
 --------------090001050406070603010704
 Content-Type: text/plain; charset=UTF-8;
  name="setfsent-cloexec.patch"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: attachment;
  filename="setfsent-cloexec.patch"
 
 --- lib/libc/gen/fstab.c.orig	2012-04-17 14:54:01.000000000 +0300
 +++ lib/libc/gen/fstab.c	2012-06-14 07:30:23.000000000 +0300
 @@ -45,6 +45,7 @@
  #include <stdlib.h>
  #include <string.h>
  #include <unistd.h>
 +#include <fcntl.h>
  #include "un-namespace.h"
  
  static FILE *_fs_fp;
 @@ -258,6 +259,11 @@
  			setfstab(getenv("PATH_FSTAB"));
  	}
  	if ((_fs_fp = fopen(path_fstab, "r")) != NULL) {
 +		int	fd;
 +
 +		fd = fileno (_fs_fp);
 +		(void) _fcntl (fd, F_SETFD, FD_CLOEXEC);
 +
  		LineNo = 0;
  		return(1);
  	}
 
 --------------090001050406070603010704--
Responsible-Changed-From-To: freebsd-bugs->freebsd-net 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Thu Jun 14 06:08:59 UTC 2012 
Responsible-Changed-Why:  
with bugmeister hat, assign this to net@ mostly in the hopes that it 
will achieve higher visibility.  OTOH maybe I should have assigned it 
to freebsd-fs@.  Er, too late now that I have the editor window open ... 

http://www.freebsd.org/cgi/query-pr.cgi?pr=169023 
Responsible-Changed-From-To: freebsd-net->freebsd-fs 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Thu Jun 14 06:10:49 UTC 2012 
Responsible-Changed-Why:  
With bugmeister hat, try to assign this to fs@ to see if it can achieve 
some higher visibility. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=169023 
Responsible-Changed-From-To: freebsd-fs->kib 
Responsible-Changed-By: kib 
Responsible-Changed-When: Thu Jun 14 09:01:53 UTC 2012 
Responsible-Changed-Why:  
Take to see followup. 

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

From: Konstantin Belousov <kostikbel@gmail.com>
To: bug-followup@FreeBSD.org, jau@iki.fi
Cc:  
Subject: Re: kern/169023: [libc] [patch] setfsent(), getfsent(), etc. leave /etc/fstab open after exec()
Date: Thu, 14 Jun 2012 12:01:19 +0300

 --/Kwy1es1GwkEJhNg
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 Content-Transfer-Encoding: quoted-printable
 
 I do not like the fcntl() use, it still leaves a window were other thread
 performing exec() causes fd leak. Please see the patch below.
 
 diff --git a/lib/libc/gen/fstab.c b/lib/libc/gen/fstab.c
 index b2c28ad..882c57f 100644
 --- a/lib/libc/gen/fstab.c
 +++ b/lib/libc/gen/fstab.c
 @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
  #include <sys/stat.h>
 =20
  #include <errno.h>
 +#include <fcntl.h>
  #include <fstab.h>
  #include <paths.h>
  #include <stdio.h>
 @@ -246,6 +247,8 @@ getfsfile(name)
  int=20
  setfsent()
  {
 +	int fd;
 +
  	if (_fs_fp) {
  		rewind(_fs_fp);
  		LineNo =3D 0;
 @@ -257,11 +260,18 @@ setfsent()
  		else
  			setfstab(getenv("PATH_FSTAB"));
  	}
 -	if ((_fs_fp =3D fopen(path_fstab, "r")) !=3D NULL) {
 +	fd =3D _open(path_fstab, O_RDONLY | O_CLOEXEC);
 +	if (fd =3D=3D -1) {
 +		error(errno);
 +		return (0);
 +	}
 +	_fs_fp =3D fdopen(fd, "r");
 +	if (_fs_fp  !=3D NULL) {
  		LineNo =3D 0;
  		return(1);
  	}
  	error(errno);
 +	_close(fd);
  	return(0);
  }
 =20
 
 --/Kwy1es1GwkEJhNg
 Content-Type: application/pgp-signature
 Content-Disposition: inline
 
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.12 (FreeBSD)
 
 iEYEARECAAYFAk/ZqF4ACgkQC3+MBN1Mb4hJrACggztgcTz6bJUyOBtYNjCcPzK2
 vMgAoMp6xpkbg3Gs+nyOtRb2VMPQBDxq
 =i60o
 -----END PGP SIGNATURE-----
 
 --/Kwy1es1GwkEJhNg--

From: "Jukka A. Ukkonen" <ext-jukka.1.ukkonen@nokia.com>
To: bug-followup@FreeBSD.org, jau@iki.fi
Cc:  
Subject: Re: kern/169023: [libc] [patch] setfsent(), getfsent(), etc. leave
 /etc/fstab open after exec()
Date: Thu, 14 Jun 2012 14:38:05 +0300

 K. you have it exactly right...
 Now that there is the O_CLOEXEC flag for open() and
 the target is a normal file, handling it all atomically
 inside open() is the way to go.
 --jau

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/169023: commit references a PR
Date: Thu, 14 Jun 2012 12:28:59 +0000 (UTC)

 Author: kib
 Date: Thu Jun 14 12:28:43 2012
 New Revision: 237061
 URL: http://svn.freebsd.org/changeset/base/237061
 
 Log:
   Make sure that fstab fd is not leaked on exec.
   
   PR:  kern/169023
   Submitted by:	Jukka Ukkonen <jau iki fi>
   MFC after:	1 week
 
 Modified:
   head/lib/libc/gen/fstab.c
 
 Modified: head/lib/libc/gen/fstab.c
 ==============================================================================
 --- head/lib/libc/gen/fstab.c	Thu Jun 14 11:39:43 2012	(r237060)
 +++ head/lib/libc/gen/fstab.c	Thu Jun 14 12:28:43 2012	(r237061)
 @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
  #include <sys/stat.h>
  
  #include <errno.h>
 +#include <fcntl.h>
  #include <fstab.h>
  #include <paths.h>
  #include <stdio.h>
 @@ -246,6 +247,8 @@ getfsfile(name)
  int 
  setfsent()
  {
 +	int fd;
 +
  	if (_fs_fp) {
  		rewind(_fs_fp);
  		LineNo = 0;
 @@ -257,11 +260,18 @@ setfsent()
  		else
  			setfstab(getenv("PATH_FSTAB"));
  	}
 -	if ((_fs_fp = fopen(path_fstab, "r")) != NULL) {
 +	fd = _open(path_fstab, O_RDONLY | O_CLOEXEC);
 +	if (fd == -1) {
 +		error(errno);
 +		return (0);
 +	}
 +	_fs_fp = fdopen(fd, "r");
 +	if (_fs_fp  != NULL) {
  		LineNo = 0;
  		return(1);
  	}
  	error(errno);
 +	_close(fd);
  	return(0);
  }
  
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/169023: commit references a PR
Date: Thu, 21 Jun 2012 08:36:03 +0000 (UTC)

 Author: kib
 Date: Thu Jun 21 08:35:47 2012
 New Revision: 237361
 URL: http://svn.freebsd.org/changeset/base/237361
 
 Log:
   MFC r237061:
   Make sure that fstab fd is not leaked on exec.
   
   PR:	kern/169023
 
 Modified:
   stable/9/lib/libc/gen/fstab.c
 Directory Properties:
   stable/9/lib/libc/   (props changed)
 
 Modified: stable/9/lib/libc/gen/fstab.c
 ==============================================================================
 --- stable/9/lib/libc/gen/fstab.c	Thu Jun 21 07:48:14 2012	(r237360)
 +++ stable/9/lib/libc/gen/fstab.c	Thu Jun 21 08:35:47 2012	(r237361)
 @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
  #include <sys/stat.h>
  
  #include <errno.h>
 +#include <fcntl.h>
  #include <fstab.h>
  #include <paths.h>
  #include <stdio.h>
 @@ -246,6 +247,8 @@ getfsfile(name)
  int 
  setfsent()
  {
 +	int fd;
 +
  	if (_fs_fp) {
  		rewind(_fs_fp);
  		LineNo = 0;
 @@ -257,11 +260,18 @@ setfsent()
  		else
  			setfstab(getenv("PATH_FSTAB"));
  	}
 -	if ((_fs_fp = fopen(path_fstab, "r")) != NULL) {
 +	fd = _open(path_fstab, O_RDONLY | O_CLOEXEC);
 +	if (fd == -1) {
 +		error(errno);
 +		return (0);
 +	}
 +	_fs_fp = fdopen(fd, "r");
 +	if (_fs_fp  != NULL) {
  		LineNo = 0;
  		return(1);
  	}
  	error(errno);
 +	_close(fd);
  	return(0);
  }
  
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->closed 
State-Changed-By: kib 
State-Changed-When: Thu Jun 21 08:55:34 UTC 2012 
State-Changed-Why:  
Merged to 8 and 9. 

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

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/169023: commit references a PR
Date: Thu, 21 Jun 2012 08:55:36 +0000 (UTC)

 Author: kib
 Date: Thu Jun 21 08:55:07 2012
 New Revision: 237362
 URL: http://svn.freebsd.org/changeset/base/237362
 
 Log:
   MFC r237061:
   Make sure that fstab fd is not leaked on exec.
   
   PR:	kern/169023
 
 Modified:
   stable/8/lib/libc/gen/fstab.c
 Directory Properties:
   stable/8/lib/libc/   (props changed)
 
 Modified: stable/8/lib/libc/gen/fstab.c
 ==============================================================================
 --- stable/8/lib/libc/gen/fstab.c	Thu Jun 21 08:35:47 2012	(r237361)
 +++ stable/8/lib/libc/gen/fstab.c	Thu Jun 21 08:55:07 2012	(r237362)
 @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
  #include <sys/stat.h>
  
  #include <errno.h>
 +#include <fcntl.h>
  #include <fstab.h>
  #include <paths.h>
  #include <stdio.h>
 @@ -246,6 +247,8 @@ getfsfile(name)
  int 
  setfsent()
  {
 +	int fd;
 +
  	if (_fs_fp) {
  		rewind(_fs_fp);
  		LineNo = 0;
 @@ -257,11 +260,18 @@ setfsent()
  		else
  			setfstab(getenv("PATH_FSTAB"));
  	}
 -	if ((_fs_fp = fopen(path_fstab, "r")) != NULL) {
 +	fd = _open(path_fstab, O_RDONLY | O_CLOEXEC);
 +	if (fd == -1) {
 +		error(errno);
 +		return (0);
 +	}
 +	_fs_fp = fdopen(fd, "r");
 +	if (_fs_fp  != NULL) {
  		LineNo = 0;
  		return(1);
  	}
  	error(errno);
 +	_close(fd);
  	return(0);
  }
  
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
>Unformatted:
