[138935] trunk/base/src/darwintracelib1.0/darwintrace.c

cal at macports.org cal at macports.org
Thu Jul 23 13:49:56 PDT 2015


Revision: 138935
          https://trac.macports.org/changeset/138935
Author:   cal at macports.org
Date:     2015-07-23 13:49:56 -0700 (Thu, 23 Jul 2015)
Log Message:
-----------
base: darwintrace: set close-on-exec on darwintrace socket

While there is currently no indication that this has been a significant problem
so far, it could certainly happen. Let's do the safe thing and set
close-on-exec (our socket cannot be used after exec anyway).

Modified Paths:
--------------
    trunk/base/src/darwintracelib1.0/darwintrace.c

Modified: trunk/base/src/darwintracelib1.0/darwintrace.c
===================================================================
--- trunk/base/src/darwintracelib1.0/darwintrace.c	2015-07-23 13:06:36 UTC (rev 138934)
+++ trunk/base/src/darwintracelib1.0/darwintrace.c	2015-07-23 20:49:56 UTC (rev 138935)
@@ -44,6 +44,7 @@
 #endif
 
 #include <errno.h>
+#include <fcntl.h>
 #include <inttypes.h>
 #include <pthread.h>
 #include <string.h>
@@ -377,6 +378,7 @@
 
 	if (__darwintrace_sock() == NULL) {
 		int sock;
+		int sockflags;
 		FILE *stream;
 		struct sockaddr_un sun;
 
@@ -392,6 +394,29 @@
 			abort();
 		}
 
+		/* Set the close-on-exec flag as early as possible after the socket
+		 * creation. On OS X, there is no way to do this race-condition free
+		 * unless you synchronize around creation and fork(2) -- however,
+		 * blocking in this function is not acceptable for darwintrace, because
+		 * it could possibly run in a signal handler, leading to a deadlock.
+		 *
+		 * The close-on-exec flag is needed because we're using a thread-local
+		 * variable to hold a reference to this socket, but multi-threaded
+		 * programs that fork will only clone the thread that calls fork(2),
+		 * which leaves us with no reference to the other sockets (which are
+		 * inherited, because FDs are process-wide). Consequently, this can
+		 * lead to a resource leak.
+		 */
+		if (-1 == (sockflags = fcntl(sock, F_GETFD))) {
+			perror("darwintrace: fcntl(F_GETFD)");
+			abort();
+		}
+		sockflags |= FD_CLOEXEC;
+		if (-1 == fcntl(sock, F_SETFD, sockflags)) {
+			perror("darwintrace: fcntl(F_SETFD, flags | FD_CLOEXEC)");
+			abort();
+		}
+
 		if (strlen(__env_darwintrace_log) > sizeof(sun.sun_path) - 1) {
 			fprintf(stderr, "darwintrace: Can't connect to socket %s: name too long\n", __env_darwintrace_log);
 			abort();
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/macports-changes/attachments/20150723/3b716d27/attachment.html>


More information about the macports-changes mailing list