Skip to content

Set CLOEXEC on the listen socket when forking FPM children #11708

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

Closed
wants to merge 1 commit into from

Conversation

mikhainin
Copy link
Contributor

It doesn't look like a good idea to invoke fork() from the FPM worker but sometimes people may do this. If this happens, the socket may leak into the new process and break something.

The socket still can be accessed via fopren('php://fd/<FD>') but not sure if we can/should do anything about that

@mikhainin mikhainin requested a review from bukka as a code owner July 14, 2023 17:44
@mikhainin mikhainin force-pushed the cloexec-listen-socket-fpm branch from 4633f53 to 360b165 Compare July 14, 2023 19:29
@mikhainin
Copy link
Contributor Author

Basically, that was a real issue in our project.

Not sure if introducing the new function is a good idea - I will be happy to move it somewhere. It is probably worth adding a test. Let me know if you have any idea how

Copy link
Member

@bukka bukka left a comment

Choose a reason for hiding this comment

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

This is a known issue and there are some related reports / discussion about this:

From re-reading the discussions I was a bit worried about stdin but not really sure why. It would be definitely good to test if it is possible to currently read from stdin in some useful way in the execed script.

Some of the reports also contained some script that could be used for the test so take a look. It would be good to have some sort of test even if it was just Linux specific.

@@ -167,6 +167,26 @@ struct fpm_child_s *fpm_child_find(pid_t pid) /* {{{ */
}
/* }}} */

static int fpm_child_cloexec(void) /* {{{ */
Copy link
Member

Choose a reason for hiding this comment

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

NIT: we no longer use {{{ and }}} for new functions so please remove it.

@mikhainin mikhainin force-pushed the cloexec-listen-socket-fpm branch from 360b165 to ad4639b Compare July 17, 2023 11:07
@mikhainin
Copy link
Contributor Author

Sure, I removed {{{ and will look into implementing tests.

@mikhainin
Copy link
Contributor Author

mikhainin commented Jul 28, 2023

It actually looks like the stdin is already set to /dev/null

I feel like it happens in the fpm_stdio_init_main()

Master process:

lsof -P | fgrep -w 77376
php-fpm   77376 mikhailgalanin  cwd       DIR               1,18        2080             3682735 /Users/mikhailgalanin/src/php-src
php-fpm   77376 mikhailgalanin  txt       REG               1,18    50481108           227463483 /Users/mikhailgalanin/src/php-src/sapi/fpm/php-fpm
php-fpm   77376 mikhailgalanin  txt       REG               1,18     1173952            19102973 /opt/homebrew/Cellar/libiconv/1.17/lib/libiconv.2.dylib
php-fpm   77376 mikhailgalanin  txt       REG               1,18     3430736           185506511 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.3/lib/darwin/libclang_rt.asan_osx_dynamic.dylib
php-fpm   77376 mikhailgalanin    0u      CHR                3,2         0t0                 335 /dev/null
php-fpm   77376 mikhailgalanin    1u      CHR                3,2         0t0                 335 /dev/null
php-fpm   77376 mikhailgalanin    2u      CHR              16,20   0t2140675                1359 /dev/ttys020
php-fpm   77376 mikhailgalanin    3u      CHR              16,20   0t2140675                1359 /dev/ttys020
php-fpm   77376 mikhailgalanin    4w      REG               1,18           0           227468843 /Users/mikhailgalanin/src/php-src/log/php-fpm.log
php-fpm   77376 mikhailgalanin    5u     unix  0xc97642ec9b68521         0t0                     ->0xc97642ec9b685e9
php-fpm   77376 mikhailgalanin    6u     unix  0xc97642ec9b685e9         0t0                     ->0xc97642ec9b68521
php-fpm   77376 mikhailgalanin    7u     IPv6  0xc97643865f6bfe9         0t0                 TCP *:8002 (LISTEN)
php-fpm   77376 mikhailgalanin    8u   KQUEUE                                                    count=0, state=0xa

Worker:

php-fpm   77377 mikhailgalanin  cwd       DIR               1,18        2080             3682735 /Users/mikhailgalanin/src/php-src
php-fpm   77377 mikhailgalanin  txt       REG               1,18    50481108           227463483 /Users/mikhailgalanin/src/php-src/sapi/fpm/php-fpm
php-fpm   77377 mikhailgalanin  txt       REG               1,18     1173952            19102973 /opt/homebrew/Cellar/libiconv/1.17/lib/libiconv.2.dylib
php-fpm   77377 mikhailgalanin  txt       REG               1,18     3430736           185506511 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/14.0.3/lib/darwin/libclang_rt.asan_osx_dynamic.dylib
php-fpm   77377 mikhailgalanin  txt       REG               1,15  1591853056              121701 /System/Volumes/Preboot/Cryptexes/OS/System/Library/dyld/dyld_shared_cache_arm64e
php-fpm   77377 mikhailgalanin    0u      CHR                3,2         0t0                 335 /dev/null
php-fpm   77377 mikhailgalanin    1u      CHR                3,2         0t0                 335 /dev/null
php-fpm   77377 mikhailgalanin    2u      CHR                3,2         0t0                 335 /dev/null
php-fpm   77377 mikhailgalanin    3u      CHR              16,20   0t2140675                1359 /dev/ttys020
php-fpm   77377 mikhailgalanin    8u     IPv6  0xc97643865f6bfe9         0t0                 TCP *:8002 (LISTEN)

@mikhainin mikhainin changed the title Set CLOEXEC on listened sockets when forking FPM children Set CLOEXEC on the listen socket when forking FPM children Jul 28, 2023
@mikhainin mikhainin force-pushed the cloexec-listen-socket-fpm branch 2 times, most recently from aa0f8bd to 4aba136 Compare July 28, 2023 12:34
@mikhainin mikhainin marked this pull request as draft July 28, 2023 14:27
@mikhainin mikhainin force-pushed the cloexec-listen-socket-fpm branch from ae2c2ac to 90ac9e0 Compare July 28, 2023 16:32
@mikhainin mikhainin marked this pull request as ready for review July 28, 2023 16:34
@mikhainin
Copy link
Contributor Author

Hi @bukka,

I just checked the issues you mentioned and it looks like the main concern (listening socket = stdin) appeared by mistake. It doesn't seem to happen on Linux or MacOS.

I added a test and also set CLOEXEC on the accepted socket in the FPM worker (which also leaked).

@mikhainin mikhainin requested a review from bukka August 10, 2023 14:34
@bukka bukka force-pushed the cloexec-listen-socket-fpm branch from 90ac9e0 to 06af583 Compare August 26, 2023 13:11
@bukka bukka closed this in 418cdc0 Aug 26, 2023
@bukka
Copy link
Member

bukka commented Aug 26, 2023

@mikhainin Finally got time to properly test it. I have done some modifications in couple of places but in general it was good. All merged now.

@andypost
Copy link
Contributor

Filed follow-up as the test is borked for Alpinelinux #12077

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants