-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
remove unnecessary workaround for fclose() on OpenBSD #537
base: master
Are you sure you want to change the base?
Conversation
i'd like to believe this has been fixed, but the only certain way to test it imo is to set a breakpoint on libc close and then call fclose() - preferably on a //edit: and in case it isn't clear, see whether the breakpoint is hit //edit2: i just realized we actually had a configure check for this behaviour - which will (or should) make this work for any OpenBSD version - what's the disadvantage of keeping it ? (apart from having a runtime test that's not cross-compile compatible) |
Turns out the test in proxychains-ng hasn't worked in 8 years. See this commit: https://cvsweb.openbsd.org/src/lib/libc/stdio/fclose.c?rev=1.10&content-type=text/x-cvsweb-markup
I modified the earlier test program to do nothing but fclose() stdin and a FILE it opened itself: #include <sys/utsname.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
int main()
{
struct utsname os;
int fd;
FILE *file;
char *closed_str[] = {" not", ""};
uname(&os);
if ((fd = open("/dev/null", O_RDONLY)) == -1)
return 1;
if ((file = fdopen(fd, "rb")) == NULL)
return 1;
printf("Operating system: %s/%s %s %s\n", os.sysname, os.machine,
os.release, os.version);
fclose(stdin);
fclose(file);
} Then I ran it in gdb with breakpoint in close(). NetBSD fclose() also calls close(): Also, POSIX says:
I suppose whatever assumption proxychains-ng made need to be fixed, I just noticed the OpenBSD test wasn't detecting anything and didn't look further before making this PR, and now I'm going to bed. |
proxychains-ng didn't call fclose() in a particular FILE on OpenBSD if a test in the Makefile noticed that OpenBSD's fclose() called close() on the underlying fd of the FILE. The test hasn't worked for 8 years because an OpenBSD commit prevented the test from overriding the libc close(): https://cvsweb.openbsd.org/src/lib/libc/stdio/fclose.c?rev=1.10&content-type=text/x-cvsweb-markup >let internal calls resolve directly and not be overridable For all this time, the workaround wasn't doing anything. Additionally, behavior equivalent to calling close() on a fd is mandatory in POSIX: https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/ >The fclose() function shall perform the equivalent of a close() >on the file descriptor And finally, at least NetBSD 9.3 also uses the close() function to do the same, but there's no workaround, and no reported misbehavior when running on NetBSD to work around. Even if the test did work, all the workaround appears to do is leak a FILE.
After reading a bit more of the source code, I don't see how whether the underlying fd of a FILE is closed by fclose() has any effect on the code. The only thing the workaround seems to do is leak a FILE on OpenBSD if the compile-time test succeeds. Inside libproxychains.c's function file = fopen(...);
fgets(..., file);
#ifndef BROKEN_FCLOSE
fclose(file);
#endif There's no I've changed the commit message and force-pushed a new version, the code changes are the same as before. |
see the original research here #95 and upstream bug report here: i'm aware that the current bugfix creates an fd leak, but it was deemed better than crashing. |
It's code that isn't doing anything, the |
so to conclude, recent openbsd runs the configure check but doesn't activate the hack, whereas old openbsd versions that need the hack properly recognize it and activate it (unless a crosscompiler is used) ? |
Test program:
Output:
I tried an earlier version of the test program (it only tests stdin) on a bunch of others too to see if it's a thing elsewhere: