Bug 83899

Summary: test for FD_CLOEXEC seems to be unreliable on NetBSD
Product: dbus Reporter: Simon McVittie <smcv>
Component: coreAssignee: D-Bus Maintainers <dbus>
Status: RESOLVED FIXED QA Contact: D-Bus Maintainers <dbus>
Severity: normal    
Priority: low CC: jmmv, msniko14, prlw1
Version: 1.5Keywords: love
Hardware: All   
OS: All   
Whiteboard:
i915 platform: i915 features:

Description Simon McVittie 2014-09-15 17:15:15 UTC
To ensure that child processes aren't going to inherit fds that they shouldn't, if compiled with tests, we assert that all fds >= 3 are cloexec:

#ifdef DBUS_ENABLE_EMBEDDED_TESTS
  max_open = sysconf (_SC_OPEN_MAX);
¯¯
  for (i = 3; i < max_open; i++)
    {
      int retval;

      if (i == child_err_report_fd)
        continue;
¯¯¯¯¯¯
      retval = fcntl (i, F_GETFD);

      if (retval != -1 && !(retval & FD_CLOEXEC))
»·······_dbus_warn ("Fd %d did not have the close-on-exec flag set!\n", i);
    }
#endif

According to manpages-posix, this ought to be OK: fcntl(3posix) says "The fcntl() function shall fail if ... EBADF: The fildes argument is not a valid open file descriptor".

However, that doesn't work on NetBSD, where fcntl F_GETFD apparently returns 0 for a few fds that are not actually open:

https://bugs.freedesktop.org/show_bug.cgi?id=69702#c22

I would like this check to be more reliable. Is there a function you can call on NetBSD which will give a reliable answer to the following question: given a small integer, is it a fd that might be passed across an exec() to our new self?

If there is no such function, then:

- perhaps we will have to stub out that check on NetBSD
  by putting it in #ifndef __NetBSD__

- as a consequence, it is possible that activated D-Bus services will
  inherit undesired fds (perhaps from bugs in BSD- or NetBSD-specific code
  paths) on NetBSD, and we won't notice
Comment 1 Simon McVittie 2014-09-16 11:15:51 UTC
From the thread starting here

http://mail-index.netbsd.org/tech-kern/2014/09/15/msg017660.html

it seems that the problem is that we're inheriting miscellaneous fds from the environment, which are not close-on-exec. So the D-Bus test framework, intended to make sure that D-Bus starts its activated services with only stdin, stdout and stderr open, has found bugs in NetBSD's GUI environment where it starts applications with more than stdin, stdout and stderr open.

One possible solution would be to iterate through fds >= 3 during test startup and make them all close-on-exec, so that only the new fds opened by libdbus are subject to this check. (This is hard to do portably, but doing the same thing as that check would be "good enough".)

Another would be to fix your GUI, or run these tests in a non-GUI environment.
Comment 2 Simon McVittie 2014-10-24 12:49:43 UTC
Attachment #108352 [details] over on Bug #73689 should fix this.
Comment 3 Ralf Habacker 2014-10-25 08:31:54 UTC
fixed with bug #73689

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.