![]() |
|
Message-ID: <0fcddca6-2081-4dbf-8f7a-de149b51d6d8@gmail.com> Date: Sat, 13 Sep 2025 17:23:44 -0400 From: Demi Marie Obenour <demiobenour@...il.com> To: Rich Felker <dalias@...c.org> Cc: musl@...ts.openwall.com Subject: Re: closefrom and close_range wrappers On 9/13/25 08:48, Rich Felker wrote: > On Fri, Sep 12, 2025 at 09:40:22PM -0400, Demi Marie Obenour wrote: >> Would it make sense for musl to provide close_range and >> closefrom? The main uses of them are to close unwanted >> FDs after a fork and before exec. close_range() can also >> be used to mark them close-on-exec instead. >> >> The main advantage of closefrom() is that it is portable >> to more systems. Closing file descriptors one doesn't own >> is not an issue because the code that does own these FDs >> will never get a chance to run. In particular, calling any >> stdio functions that use anything but stdin, stdout, and >> stderr would be UB. stdin, stdout, and stderr use FD 0, 1, >> and 2, respectively, and those are almost always left open. >> >> Yes, this is all a consequence of fork()/exec() being an >> extremely poor API, but I don't know of a better solution. >> There are third-party libraries (including glib and wlroots) >> that expect one to either use an API like this or emulate it >> by scanning /proc/self/fd (yuck). Yes, these libraries should >> be atomically setting O_CLOEXEC, but their authors disagree >> and maintaining downstream forks is not practical. > > I need to look back at where we left this last time it was discussed. > > As Laurent replied, per the standard (POSIX) these operations are > fundamentally programming errors. Closing a fd that "doesn't belong to > you" (that may be some implementation detail of the POSIX > implementation or some part of the execution environment hosting your > application) produces undefined behavior. Nonetheless, people do want > to do it for various reasons and the existing ways of doing it without > the syscall are "worse". I think this is a case where practical realities should override purity. There is too many code that will fall back to iterating over /proc/self/fd if closefrom() or close_range() isn't available. Closing an FD that happens to be a libc implementation detail is only possible if such an FD exists, which (to the best of my knowledge) is not the case. > One question that naturally arises whenever adding an interface like > this is what we do on kernel versions that lack it. Do we fail it and > leave the application to figure out what to do when it fails, or > emulate it? If taking the failing option, there's not a whole lot of > value over the caller just using syscall() directly, but maybe it > makes sense. I think there are some macro constants needed to use > the syscall that potentially make it difficult to do without libc > exposing anything (possible conflicts pulling in kernel headers). > > I'll try to find past discussion of this. If anyone else has it handy > to cite, go ahead. One advantage is that syscall() is much more error-prone and annoying to use. -- Sincerely, Demi Marie Obenour (she/her/hers) Download attachment "OpenPGP_0xB288B55FFF9C22C1.asc" of type "application/pgp-keys" (7141 bytes) Download attachment "OpenPGP_signature.asc" of type "application/pgp-signature" (834 bytes)
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.