Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 12 Jul 2012 09:41:13 GMT
From:      Jukka Ukkonen <jau@iki.fi>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   misc/169800: A merged patch to 
Message-ID:  <201207120941.q6C9fDGl039500@red.freebsd.org>
Resent-Message-ID: <201207120950.q6C9o1Bq094195@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         169800
>Category:       misc
>Synopsis:       A merged patch to
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Thu Jul 12 09:50:01 UTC 2012
>Closed-Date:
>Last-Modified:
>Originator:     Jukka Ukkonen
>Release:        FreeBSD 9.1-BETA1
>Organization:
-----
>Environment:
FreeBSD sleipnir 9.1-BETA1 FreeBSD 9.1-BETA1 #0: Thu Jul 12 11:23:31 EEST 2012     root@sleipnir:/usr/obj/usr/src/sys/Sleipnir  amd64
>Description:
The attached patch changes a number of system library functions to set
the O_CLOEXEC flag immediately while the file is being opened.
This will assure that there will be no time window between opening the file
and setting the close-on-exec flag.
Esp. in a threaded program even the small time window could cause the file
descriptors being leaked to a child program, if another independent library
module decides to call exec() inside another thread while the new file has
been opened but the close-on-exec flag has not been set yet.

NOTICE!
This patch requires as a precondition the second enhanced version of
the patch to

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


>How-To-Repeat:
See full description above.

>Fix:
Find the patch attached.

Patch attached with submission follows:

--- lib/libc/gen/getcap.c.orig	2011-09-23 03:51:37.000000000 +0300
+++ lib/libc/gen/getcap.c	2012-07-12 10:21:29.000000000 +0300
@@ -654,7 +654,7 @@
 	if (dbp == NULL)
 		dbp = db_array;
 
-	if (pfp == NULL && (pfp = fopen(*dbp, "r")) == NULL) {
+	if (pfp == NULL && (pfp = fopen(*dbp, "re")) == NULL) {
 		(void)cgetclose();
 		return (-1);
 	}
@@ -679,7 +679,7 @@
 						(void)cgetclose();
 						return (0);
 					} else if ((pfp =
-					    fopen(*dbp, "r")) == NULL) {
+						  fopen(*dbp, "re")) == NULL) {
 						(void)cgetclose();
 						return (-1);
 					} else
--- lib/libc/gen/getttyent.c.orig	2011-09-23 03:51:37.000000000 +0300
+++ lib/libc/gen/getttyent.c	2012-07-12 10:18:06.000000000 +0300
@@ -211,7 +211,7 @@
 	if (tf) {
 		rewind(tf);
 		return (1);
-	} else if ( (tf = fopen(_PATH_TTYS, "r")) )
+	} else if ( (tf = fopen(_PATH_TTYS, "re")) )
 		return (1);
 	return (0);
 }
--- lib/libc/gen/getusershell.c.orig	2011-09-23 03:51:37.000000000 +0300
+++ lib/libc/gen/getusershell.c	2012-07-12 10:24:29.000000000 +0300
@@ -121,7 +121,7 @@
 		sl_free(sl, 1);
 	sl = sl_init();
 
-	if ((fp = fopen(_PATH_SHELLS, "r")) == NULL)
+	if ((fp = fopen(_PATH_SHELLS, "re")) == NULL)
 		return NS_UNAVAIL;
 
 	cp = line;
--- lib/libc/gen/getutxent.c.orig	2012-03-02 23:38:27.000000000 +0200
+++ lib/libc/gen/getutxent.c	2012-07-12 10:27:07.000000000 +0300
@@ -66,7 +66,7 @@
 
 	if (uf != NULL)
 		fclose(uf);
-	uf = fopen(file, "r");
+	uf = fopen(file, "re");
 	if (uf == NULL)
 		return (-1);
 
--- cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c.orig	2012-06-14 22:27:17.000000000 +0300
+++ cddl/contrib/opensolaris/lib/libdtrace/common/dt_open.c	2012-06-14 22:27:30.000000000 +0300
@@ -1061,13 +1061,20 @@
 	 */
 	dt_provmod_open(&provmod, &df);
 
-	dtfd = open("/dev/dtrace/dtrace", O_RDWR);
+/*
+ *  In case it is not defined, we define it temporarily to harmless 0.
+ */
+#if !defined(O_CLOEXEC)
+#  define O_CLOEXEC	0
+#endif
+
+	dtfd = open("/dev/dtrace/dtrace", O_RDWR | O_CLOEXEC);
 	err = errno; /* save errno from opening dtfd */
 
 #if defined(sun)
 	ftfd = open("/dev/dtrace/provider/fasttrap", O_RDWR);
 #else
-	ftfd = open("/dev/dtrace/fasttrap", O_RDWR);
+	ftfd = open("/dev/dtrace/fasttrap", O_RDWR | O_CLOEXEC);
 #endif
 	fterr = ftfd == -1 ? errno : 0; /* save errno from open ftfd */
 
@@ -1097,8 +1104,11 @@
 		return (set_open_errno(dtp, errp, err));
 	}
 
+#if (O_CLOEXEC == 0)
 	(void) fcntl(dtfd, F_SETFD, FD_CLOEXEC);
 	(void) fcntl(ftfd, F_SETFD, FD_CLOEXEC);
+#  undef O_CLOEXEC
+#endif
 
 alloc:
 	if ((dtp = malloc(sizeof (dtrace_hdl_t))) == NULL)
--- lib/libfetch/file.c.orig	2012-05-26 19:34:39.000000000 +0300
+++ lib/libfetch/file.c	2012-07-12 10:30:20.000000000 +0300
@@ -48,7 +48,7 @@
 	if (us && fetchStatFile(u, us, flags) == -1)
 		return (NULL);
 
-	f = fopen(u->doc, "r");
+	f = fopen(u->doc, "re");
 
 	if (f == NULL)
 		fetch_syserr();
@@ -58,7 +58,6 @@
 		fetch_syserr();
 	}
 
-	fcntl(fileno(f), F_SETFD, FD_CLOEXEC);
 	return (f);
 }
 
@@ -74,9 +73,9 @@
 	FILE *f;
 
 	if (CHECK_FLAG('a'))
-		f = fopen(u->doc, "a");
+		f = fopen(u->doc, "ae");
 	else
-		f = fopen(u->doc, "w+");
+		f = fopen(u->doc, "w+e");
 
 	if (f == NULL)
 		fetch_syserr();
@@ -86,7 +85,6 @@
 		fetch_syserr();
 	}
 
-	fcntl(fileno(f), F_SETFD, FD_CLOEXEC);
 	return (f);
 }
 
--- lib/libkvm/kvm.c.orig	2012-06-17 17:48:21.000000000 +0300
+++ lib/libkvm/kvm.c	2012-06-17 17:55:25.000000000 +0300
@@ -166,7 +166,7 @@
 	if (mf == 0)
 		mf = _PATH_MEM;
 
-	if ((kd->pmfd = open(mf, flag, 0)) < 0) {
+	if ((kd->pmfd = open(mf, (flag | O_CLOEXEC), 0)) < 0) {
 		_kvm_syserr(kd, kd->program, "%s", mf);
 		goto failed;
 	}
@@ -179,10 +179,7 @@
 		_kvm_syserr(kd, kd->program, "empty file");
 		goto failed;
 	}
-	if (fcntl(kd->pmfd, F_SETFD, FD_CLOEXEC) < 0) {
-		_kvm_syserr(kd, kd->program, "%s", mf);
-		goto failed;
-	}
+
 	if (S_ISCHR(st.st_mode)) {
 		/*
 		 * If this is a character special device, then check that
@@ -191,17 +188,16 @@
 		 * case you're working with a live kernel.)
 		 */
 		if (strcmp(mf, _PATH_DEVNULL) == 0) {
-			kd->vmfd = open(_PATH_DEVNULL, O_RDONLY);
+			kd->vmfd = open(_PATH_DEVNULL,
+					(O_RDONLY | O_CLOEXEC));
 			return (kd);
 		} else if (strcmp(mf, _PATH_MEM) == 0) {
-			if ((kd->vmfd = open(_PATH_KMEM, flag)) < 0) {
-				_kvm_syserr(kd, kd->program, "%s", _PATH_KMEM);
-				goto failed;
-			}
-			if (fcntl(kd->vmfd, F_SETFD, FD_CLOEXEC) < 0) {
+			if ((kd->vmfd = open(_PATH_KMEM, 
+					     (flag | O_CLOEXEC))) < 0) {
 				_kvm_syserr(kd, kd->program, "%s", _PATH_KMEM);
 				goto failed;
 			}
+
 			return (kd);
 		}
 	}
@@ -210,14 +206,11 @@
 	 * Initialize the virtual address translation machinery,
 	 * but first setup the namelist fd.
 	 */
-	if ((kd->nlfd = open(uf, O_RDONLY, 0)) < 0) {
-		_kvm_syserr(kd, kd->program, "%s", uf);
-		goto failed;
-	}
-	if (fcntl(kd->nlfd, F_SETFD, FD_CLOEXEC) < 0) {
+	if ((kd->nlfd = open(uf, (O_RDONLY | O_CLOEXEC), 0)) < 0) {
 		_kvm_syserr(kd, kd->program, "%s", uf);
 		goto failed;
 	}
+
 	if (strncmp(mf, _PATH_FWMEM, strlen(_PATH_FWMEM)) == 0)
 		kd->rawdump = 1;
 	if (_kvm_initvtop(kd) < 0)


>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201207120941.q6C9fDGl039500>