]> git.openfabrics.org - ~shefty/librdmacm.git/commitdiff
Open files with "close on exec" flag
authorYann Droneaud <ydroneaud@opteya.com>
Tue, 16 Jul 2013 21:59:52 +0000 (23:59 +0200)
committerSean Hefty <sean.hefty@intel.com>
Wed, 17 Jul 2013 04:16:47 +0000 (21:16 -0700)
File opened by librdmacm are not supposed to be inherited across
exec*(), most of the files are of no use for another program, and
others cannot be used without the associated memory mapping.

This patch changes fopen() open() and socket() to always set
close on exec flag.

This patch also add checks to configure to guess if fopen() supports
"e" flag. If O_CLOEXEC and SOCK_CLOEXEC are supported, fopen() should
support "e". If not supported, its discarded according to POSIX. Many
operating systems have support for fopen("e").

You might find more information about close on exec in the following articles:

- "Excuse me son, but your code is leaking !!!" by Dan Walsh
  http://danwalsh.livejournal.com/53603.html

- "Secure File Descriptor Handling" by Ulrich Drepper
  http://udrepper.livejournal.com/20407.html

Note: this patch won't set close on exec flag on file descriptors
created by the kernel for completion channel and such.
This is addressed by another kernel patch.

Signed-off-by: Yann Droneaud <ydroneaud@opteya.com>
Signed-off-by: Sean Hefty <sean.hefty@intel.com>
configure.ac
src/acm.c
src/cma.c

index 807470f1633e2f9221e51c8aac02899d29de4e2e..31b1a0e43b6e8238111bf5a0b09cf28088caf327 100644 (file)
@@ -78,6 +78,30 @@ AC_CHECK_HEADER(infiniband/acm.h,
                AC_DEFINE(DEFINE_ACM_MSG, 1, [adding ACM message definition]),
                        [#include <infiniband/acm.h>]), [])
 
+dnl Checks close on exec support
+AC_CHECK_HEADERS([fcntl.h sys/socket.h])
+
+AC_CHECK_DECLS([O_CLOEXEC],,[AC_DEFINE([O_CLOEXEC],[0], [Defined to 0 if not provided])],
+[[
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+]])
+AC_CHECK_DECLS([SOCK_CLOEXEC],,[AC_DEFINE([SOCK_CLOEXEC],[0],[Defined to 0 if not provided])],
+[[
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+]])
+
+AC_CACHE_CHECK(for close on exec modifier for fopen(), ac_cv_feature_stream_cloexec_flag,
+   [if test $ac_cv_have_decl_O_CLOEXEC = yes ; then
+        if test $ac_cv_have_decl_SOCK_CLOEXEC = yes ; then
+            ac_cv_feature_stream_cloexec_flag="e"
+        fi
+    fi])
+AC_DEFINE_UNQUOTED([STREAM_CLOEXEC], "$ac_cv_feature_stream_cloexec_flag", [fopen() modifier for setting close on exec flag])
+
 AC_CACHE_CHECK(whether ld accepts --version-script, ac_cv_version_script,
     if test -n "`$LD --help < /dev/null 2>/dev/null | grep version-script`"; then
         ac_cv_version_script=yes
index c9ca5b56ef4d256aa82eaa76d8e28fce7c29e378..6e8e173f26e5bca452d91198f232788589aba753 100755 (executable)
--- a/src/acm.c
+++ b/src/acm.c
@@ -80,7 +80,7 @@ static int ucma_set_server_port(void)
 {
        FILE *f;
 
-       if ((f = fopen("/var/run/ibacm.port", "r"))) {
+       if ((f = fopen("/var/run/ibacm.port", "r" STREAM_CLOEXEC))) {
                fscanf(f, "%hu", (unsigned short *) &server_port);
                fclose(f);
        }
@@ -100,7 +100,7 @@ void ucma_ib_init(void)
        if (!ucma_set_server_port())
                goto out;
 
-       sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+       sock = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
        if (sock < 0)
                goto out;
 
index 2fb9913ae6c69c29c74a27ff32955ca5fa7f3eea..baebecdd96322341bc59f20dc093554609ac9d5e 100755 (executable)
--- a/src/cma.c
+++ b/src/cma.c
@@ -328,7 +328,7 @@ struct rdma_event_channel *rdma_create_event_channel(void)
        if (!channel)
                return NULL;
 
-       channel->fd = open("/dev/infiniband/rdma_cm", O_RDWR);
+       channel->fd = open("/dev/infiniband/rdma_cm", O_RDWR | O_CLOEXEC);
        if (channel->fd < 0) {
                fprintf(stderr, PFX "Fatal: unable to open /dev/infiniband/rdma_cm\n");
                goto err;