Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make file descriptors from stdlib non-inheritable by default #13201

Merged
merged 22 commits into from
Apr 20, 2020

Conversation

alaviss
Copy link
Collaborator

@alaviss alaviss commented Jan 20, 2020

Fixes #6602. Please refer to the linked issue for the rationale.

This is still pretty much a WIP. The final goal here is to make all file descriptors created from stdlib's high-level abstractions non-inheritable by default.

@alaviss alaviss force-pushed the fd-no-leak branch 2 times, most recently from e72420e to cbf71e0 Compare January 20, 2020 07:56
@Varriount
Copy link
Contributor

@alaviss and others: This might be useful - https://www.python.org/dev/peps/pep-0446/

@Araq
Copy link
Member

Araq commented Jan 20, 2020

I'm not a fan of fixing UNIX bugs in Nim, but I won't fight it.

@alaviss
Copy link
Collaborator Author

alaviss commented Jan 20, 2020

I'm not a fan of fixing UNIX bugs in Nim, but I won't fight it.

Windows leak handles too, unless you manually use Win32 API.

@Araq
Copy link
Member

Araq commented Jan 20, 2020

Windows leak handles too, unless you manually use Win32 API.

I always wanted to use the Win32 API directly for IO indeed.

@alaviss alaviss force-pushed the fd-no-leak branch 2 times, most recently from 91aa08f to 741130e Compare January 20, 2020 11:12
@disruptek
Copy link
Contributor

But isn't this a heavy-handed change for the language to impose on the user? How does the user get around it?

@alaviss
Copy link
Collaborator Author

alaviss commented Jan 20, 2020

But isn't this a heavy-handed change for the language to impose on the user? How does the user get around it?

By marking file descriptors that you want to pass down with setInheritable().

And I don't even think most users will ever notice these changes. Maybe they will find out that their web server no longer error out due to "address in use" when it restarts (see #6602), but for the few that actually use this functionality, chances are that they know how to do it correctly.

@disruptek
Copy link
Contributor

That makes sense; thanks for explaining it.

@alaviss alaviss marked this pull request as ready for review January 22, 2020 15:46
@alaviss
Copy link
Collaborator Author

alaviss commented Jan 22, 2020

That should be about all of them. Please let me know if I missed any.

@alaviss
Copy link
Collaborator Author

alaviss commented Jan 22, 2020

Reopening for Windows CI which failed for unrelated reasons.

@alaviss alaviss closed this Jan 22, 2020
@alaviss alaviss reopened this Jan 22, 2020
@alaviss alaviss closed this Jan 23, 2020
@alaviss alaviss reopened this Jan 23, 2020
@Varriount
Copy link
Contributor

It's unfortunate there's no way to enable a test at compile time to list or detect inherited file descriptors

@alaviss alaviss requested a review from Araq January 23, 2020 05:50
var p = fopen(filename, FormatOpen[mode])
##
## The file handle associated with the resulting ``File`` is not inheritable.
var p = fopen(filename, FormatOpen[mode] & NoInheritFlag)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And then use no string concats here.

@Araq
Copy link
Member

Araq commented Jan 23, 2020

Please let me know if I missed any.

Ha, good one. I don't know either.

@alaviss alaviss closed this Jan 23, 2020
@alaviss alaviss reopened this Jan 23, 2020
@alaviss alaviss closed this Jan 24, 2020
@alaviss alaviss reopened this Jan 24, 2020
@alaviss alaviss requested a review from Araq January 24, 2020 05:21
@Araq
Copy link
Member

Araq commented Jan 26, 2020

There has been concerns about how this makes multi-process servers much harder to write than before. Can we add a build option like -d:nimInheritHandles for these cases and also for backwards compatibility?

File descriptors from ioselectors should no longer leaks on Linux.
Also simplified the test by using handle-type agnostic APIs to test for
validity.
The getFd proc for ioselectors_select returns a hardcoded -1
This allows for the flag to be set/unset in one syscall. While the
performance gains might be negliable, we have one less failure point
to deal with.
On Windows, the native handle is the only thing that's inheritable, thus
we can assume that users of this function will already have the handle
available to them. This also allows users to pass down file descriptors
from memfiles on Windows with ease, should that be desired.

With this, nativesockets.setInheritable can be made much simpler.
@@ -81,7 +81,7 @@ proc newSelector*[T](): Selector[T] =
# Start with a reasonable size, checkFd() will grow this on demand
const numFD = 1024

var epollFD = epoll_create(MAX_EPOLL_EVENTS)
var epollFD = epoll_create1(O_CLOEXEC)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

epoll_create1 was added to the Linux in version 2.6.27. Is it ok for Nim's minimal supported Linux version?
http://man7.org/linux/man-pages/man2/epoll_create.2.html

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's released over a decade ago, I don't see why not :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, but isn't Linux 2.4 still widely used for embedded development?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't have to care about that, since ioselectors_epoll uses eventfd(2) which is added in Linux 2.6.22.

lib/pure/ioselects/ioselectors_epoll.nim Show resolved Hide resolved
lib/pure/ioselects/ioselectors_epoll.nim Show resolved Hide resolved
lib/pure/ioselects/ioselectors_epoll.nim Show resolved Hide resolved
lib/pure/ioselects/ioselectors_epoll.nim Show resolved Hide resolved
@alaviss alaviss closed this Apr 9, 2020
@alaviss alaviss reopened this Apr 9, 2020
@kubo39
Copy link
Contributor

kubo39 commented Apr 9, 2020

I find one more case: mkstemp in posix_utils.nim, and could be replaced with mkostemp in some OSes.

@alaviss alaviss requested a review from Araq April 9, 2020 19:49
@alaviss
Copy link
Collaborator Author

alaviss commented Apr 10, 2020

@Araq It's ready for review.

@Araq Araq merged commit 1bdc30b into nim-lang:devel Apr 20, 2020
@alaviss alaviss deleted the fd-no-leak branch April 20, 2020 17:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

File descripters should be non-inheritable by default.
5 participants