close-on-exec

Thomas Klausner wiz at NetBSD.org
Thu Feb 26 01:34:04 PST 2015


On Wed, Feb 25, 2015 at 02:27:30PM -0800, Alan Coopersmith wrote:
> Solaris has the ancient support for setting the FD_CLOEXEC flag via
> fcntl() in all versions, and the more recent support for the O_CLOEXEC
> flag to open() in Solaris 11 and later, but does not yet support the
> "e" flag to fopen().  (I've filed an enhancement request to add it to
> our libc in the future, but that doesn't help today.)
> 
> I believe the most portable way to do this is:
> 
> if (!(addfp = fopen (addAuthFile, "w")))
>  	goto bad;
> else
> 	fcntl(fileno(addfp), F_SETFD, FD_CLOEXEC);
> 
> That would be subject to race conditions in multi-threaded processes, as
> described in https://udrepper.livejournal.com/20407.html, so not safe in
> libraries or programs which deliberately start multiple threads, but since
> xsm is not one of those, it should be mostly safe. (Not completely, because
> we can't be sure nothing we called in a library didn't start a thread behind
> the scenes to handle one of our requests, but without an "e" flag everywhere,
> I'm not sure what more we can do.  I have no idea how to write a configure
> check to test for fopen(..., "e") support either.)

Ok, so let's use fcntl for now, new patch attached.
 Thomas
-------------- next part --------------
>From e8ea2f72fdb8c6ab38fd8a7b76865695065283cf Mon Sep 17 00:00:00 2001
From: Thomas Klausner <wiz at NetBSD.org>
Date: Wed, 25 Feb 2015 22:22:50 +0100
Subject: [PATCH:xsm] Close file descriptors on exec.

Signed-off-by: Thomas Klausner <wiz at NetBSD.org>
---
 auth.c     | 4 ++++
 choose.c   | 2 ++
 lock.c     | 1 +
 remote.c   | 3 ++-
 restart.c  | 1 +
 saveutil.c | 3 +++
 6 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/auth.c b/auth.c
index 5b3bcac..6f355c2 100644
--- a/auth.c
+++ b/auth.c
@@ -156,24 +156,28 @@ SetAuthentication(int count, IceListenObj *listenObjs,
 
     if (!(addfp = fopen (addAuthFile, "w")))
 	goto bad;
+    (void)fcntl(fileno(addfp), F_SETFD, FD_CLOEXEC);
 
     if ((remAuthFile = unique_filename (path, ".xsm")) == NULL)
 	goto bad;
 
     if (!(removefp = fopen (remAuthFile, "w")))
 	goto bad;
+    (void)fcntl(fileno(removefp), F_SETFD, FD_CLOEXEC);
 #else
     if ((addAuthFile = unique_filename (path, ".xsm", &fd)) == NULL)
 	goto bad;
     
     if (!(addfp = fdopen(fd, "wb"))) 
 	goto bad;
+    (void)fcntl(fileno(addfp), F_SETFD, FD_CLOEXEC);
 
     if ((remAuthFile = unique_filename (path, ".xsm", &fd)) == NULL)
 	goto bad;
     
     if (!(removefp = fdopen(fd, "wb"))) 
 	goto bad;
+    (void)fcntl(fileno(removefp), F_SETFD, FD_CLOEXEC);
 #endif
 
     if ((*authDataEntries = (IceAuthDataEntry *) XtMalloc (
diff --git a/choose.c b/choose.c
index 6459b61..4ec80c3 100644
--- a/choose.c
+++ b/choose.c
@@ -98,6 +98,8 @@ GetSessionNames(int *count_ret, String **short_names_ret,
     if ((dir = opendir (path)) == NULL)
 	return 0;
 
+    (void)fcntl(dirfd(dir), F_SETFD, FD_CLOEXEC);
+
     count = 0;
 
     while ((entry = readdir (dir)) != NULL)
diff --git a/lock.c b/lock.c
index 84c0ee3..7fba1d3 100644
--- a/lock.c
+++ b/lock.c
@@ -121,6 +121,7 @@ GetLockId(const char *session_name)
     {
 	return (NULL);
     }
+    (void)fcntl(fileno(fp), F_SETFD, FD_CLOEXEC);
 
     buf[0] = '\0';
     fscanf (fp, "%255s\n", buf);
diff --git a/remote.c b/remote.c
index 54d95ac..1fe1b45 100644
--- a/remote.c
+++ b/remote.c
@@ -111,7 +111,8 @@ remote_start(const char *restart_protocol, const char *restart_machine,
 	default:		/* parent */
 
 	    close (pipefd[0]);
-	    fp = (FILE *) fdopen (pipefd[1], "w");
+	    (void)fcntl(pipefd[1], F_SETFD, FD_CLOEXEC);
+	    fp = fdopen (pipefd[1], "w");
 
 	    fprintf (fp, "CONTEXT X\n");
 	    fprintf (fp, "DIR %s\n", cwd);
diff --git a/restart.c b/restart.c
index 57663a5..6aae637 100644
--- a/restart.c
+++ b/restart.c
@@ -543,6 +543,7 @@ StartDefaultApps (void)
 	    exit (1);
 	}
     }
+    (void)fcntl(fileno(f), F_SETFD, FD_CLOEXEC);
 
     buf = NULL;
     buflen = 0;
diff --git a/saveutil.c b/saveutil.c
index 091763a..f8a7171 100644
--- a/saveutil.c
+++ b/saveutil.c
@@ -72,6 +72,7 @@ ReadSave(const char *session_name, char **sm_id)
 	*sm_id = NULL;
 	return 0;
     }
+    (void)fcntl(fileno(f), F_SETFD, FD_CLOEXEC);
     if (verbose)
 	printf("Reading session save file...\n");
 
@@ -319,6 +320,7 @@ WriteSave(const char *sm_id)
     }
     else
     {
+	(void)fcntl(fileno(f), F_SETFD, FD_CLOEXEC);
 	fprintf (f, "%d\n", SAVEFILE_VERSION);
 	fprintf (f, "%s\n", sm_id);
 
@@ -431,6 +433,7 @@ DeleteSession(const char *session_name)
     if(!f) {
 	return (0);
     }
+    (void)fcntl(fileno(f), F_SETFD, FD_CLOEXEC);
 
     buf = NULL;
     buflen = 0;
-- 
2.3.0



More information about the xorg-devel mailing list