intercept more forking functions in same way as fork()
Summary:
D7816198 added HHVM support for intercepting and blocking `fork()` calls within the main process.
However, we need to intercept more functions to get comprehensive protection:
- system()
- popen()
- posix_spawn()
- posix_spawnp()
With exception of `posix_spawn()`, all these functions have relocations in hhvm binary (i.e. some code, linked into hhvm, contains calls to these functions). E.g. `nm /usr/local/hphpi/bin/hphpi |grep 'U popen'`.
There are 2 reasons, why these functions need to be intercepted explicitly:
1. system() does not actually call fork() but makes an equivalent system call directly. The reason has something to do with thread cancelation support
2. other code in glibc call glibc fork via `__fork()`, so it is not caught by our fork intercept. We need to either intercept other functions explicitly or also intercept `__fork()` [and deal with potential inlining inside glibc]. The former approach is simpler and more robust.
There are few more glibc functions which can fork, but these are exotic and not linked into hhvm (I discovered this by grepping for fork through glibc source code):
- daemon() - it calls exit(0) in parent process, so it's extremely unlikely to show up in a library
- wordexp() - I can't even...
- grantpt() - "grant access to slave pseudo-terminal"
For now, I haven't added wrappers for these, since all of them seem unlikely to ever show up in HHVM, but I'm happy to add wrappers if someone feels the other way.
+ chipturner, who prompted me to look for more potential wuntions to intercept by asking me about popen.
I refactored the code a bit to minimize copy-pasting between 5 similar wrappers and potential for copy-paste errors. The current setup (with delegating disable check and dlsym resolution into helper function) is the best option, I could come up with. I'm open to alternative ideas on how to reduce code duplication here.
Initially I tried to keep weak symbol + fallback to dlsym approach from
D7816198. However, I ended up switching to dlsym-only approach, because I couldn't make weak symbols approach work for popen, posix_spawn and posix_spawnp. The problem: glibc doesn't export corresponding "real" symbols (e.g. `__posix_spawn`, `__new_popen`).
Reviewed By: markw65
Differential Revision:
D7922693
fbshipit-source-id:
519f29e24590164fcccc84816bca4c9cd4eaa4d2