Restore the close-on-exec and bounded reap removed by #542 - #591
Closed
somethingwithproof wants to merge 1 commit into
Closed
Restore the close-on-exec and bounded reap removed by #542#591somethingwithproof wants to merge 1 commit into
somethingwithproof wants to merge 1 commit into
Conversation
PR Cacti#542 removed both while adding unrelated poller fixes; its branch predated Cacti#557 and the base looks folded in rather than rebased. Nothing caught it: the only guard was a shell script that grepped the source, and it was deleted in the same commit. An inherited pipe write end keeps a script's reader from seeing EOF, so the thread blocks to script_timeout for a device that answered. The unbounded waitpid has no timeout at all, and the thread holds its available_scripts token while it waits. The php.c reap survived Cacti#542 and is better than what was removed, so only its pipes needed the flag. Both callers now share one helper, covered by six tests against the shipped object: two of them fail if the close-on-exec goes away again. Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Member
Author
|
Consolidated into #597, which carries this branch's commits unchanged. Every pair of these ten conflicted on Nothing here is dropped. Reopen this if you would rather review it separately. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #581.
PR #542 landed three commits after #557 and removed the process hardening #557 had just added. #542 has the lower number, so its branch predates #557 and the base appears to have been folded in rather than rebased.
git grep CLOEXECover develop currently returns nothing.What was lost
Pipes are inherited across exec.
nft_popen()creates its pipe before takingListMutex, and the entry joinsPidListonly afterposix_spawnreturns. A thread spawning inside that window produces a child holding another thread's pipe write end. The first thread never sees EOF, so it blocks toscript_timeoutand recordsUfor a data source that answered. The script-server pipes are worse: they are never inPidListat all, so every script child inheritscacti2php_pdes[1], and sincephp_close()signals the server by closing that descriptor, a child holding a duplicate keeps the server alive past shutdown.The bounded reap became an unbounded block.
exec_poll()only sendsSIGKILLon theselect()timeout branch; the normal branch reads one line and callsnft_pclose()directly. A script that prints its value and then exits slowly pins the poller thread with no timeout, across cycles, holding itsavailable_scriptstoken throughout.What this restores, and what it does not
php.ckept its bounded reap through #542 asphp_terminate_and_reap(), and that version is better than the one that was removed, so it is untouched. Only its pipes needed the flag.nft_popen.cneeded both halves.The two files had separate copies of the same close-on-exec helper. There is now one,
spine_open_pipe_cloexec(), used by both.Also restored: the
close(cacti2php_pdes[...])pair on the second pipe's failure path, dropped by the same commit, which leaked two descriptors.Kept from #542: the
free(cur)additions on twonft_popen()error paths, and theRESULTS_BUFFERbounds work inphp.c. This reverts nothing that commit got right.pipe2(pdes, O_CLOEXEC)would close the window betweenpipe()andfcntl()atomically, but it needs_GNU_SOURCEon glibc and spine defines no feature macro. Adding one is a portability decision that does not belong in a restore, so thefcntl()pair stays and the comment says why.Tests
The previous guard was
tests/regression/test_child_process_safety.sh, which grepped the source for the strings it wanted and was deleted alongside the code it protected. Six cmocka cases replace it, against the shippednft_popen.o:exec, checked by having a child look for it in/proc/self/fdReverting just the
fcntl()calls, which is what #542 did, fails two of them:The second is the interesting one:
0is the child reporting it found the descriptor.43 of 43 pass with the fix,
make checkis green on all four binaries, and the build carries the same four warnings as develop.No
CHANGELOGentry here; #578 is the changelog PR for this batch.