standard/syslog: the request shutdown hook calls closelog() even when the request never opened syslog
メンテナーはふだん 1 日以内に返信
評価
調査の方向性
無条件のcloseは ext/standard/syslog.c の PHP_RSHUTDOWN_FUNCTION(syslog) にあります。main/php_syslog.c の php_closelog() と PG(have_called_openlog) フラグ(74〜84行目付近)、および main/main.c の2317行目付近でのリセットを読んでください。openlog、closelog、syslog のいずれも呼ばないリクエストが、BG(syslog_device) を解放しつつ php_closelog() をスキップすれば完了です。issue に示されているとおり、複数リクエストを処理するマルチリクエスト SAPI 上で strace を使って複数のリクエストを確認してください。
索引モデルが issue の本文から書いたものです。
説明
Description
ext/standard/syslog.c installs an unconditional request shutdown hook:
PHP_RSHUTDOWN_FUNCTION(syslog)
{
php_closelog();
if (BG(syslog_device)) {
free(BG(syslog_device));
BG(syslog_device) = NULL;
}
return SUCCESS;
}
php_closelog() runs after every request, whether or not this request opened syslog. In a SAPI that serves more than one request per process, that closes a process-wide handle the request may not own, and the next request opens it again.
Note that the state to avoid this already exists: php_openlog() sets PG(have_called_openlog) = 1 and php_closelog() clears it (main/php_syslog.c:74-84), and php_module_startup() resets it to 0 (main/main.c:2317). The shutdown hook simply does not look at it.
Expected
A request that never calls openlog(), closelog() or syslog() should leave the process syslog handle alone. If the handle was opened outside PHP, for example by the embedding application or by a library in the same process, PHP should not close it.
Actual
Embedded SAPI, PHP 8.5.11 (Alpine 3.24.2, musl 1.2.6, OpenSSL 3.5.9), one worker process serving three requests with error_log = syslog and a script that only calls error_log("request"). strace of the worker:
1080 connect(15, {sa_family=AF_UNIX, sun_path="/dev/log"}, 12) = 0
1080 sendto(15, "<13>Oct 13 21:57:46 php: request\n", 33, 0, NULL, 0) = 33
1080 connect(14, {sa_family=AF_UNIX, sun_path="/dev/log"}, 12) = 0
1080 sendto(14, "<13>Oct 13 21:57:46 php: request\n", 33, 0, NULL, 0) = 33
1080 connect(14, {sa_family=AF_UNIX, sun_path="/dev/log"}, 12) = 0
1080 sendto(14, "<13>Oct 13 21:57:46 php: request\n", 33, 0, NULL, 0) = 33
Three requests, three connects: the handle does not survive a request boundary. In the same process, a host that opened syslog before running PHP loses it when the first request ends. php-fpm works around this by calling php_closelog() itself when it takes over the child, with the comment "ensure to close syslog not to interrupt with PHP syslog code" (sapi/fpm/fpm/fpm_stdio.c:144), which is the same interaction seen from the other side.
Suggested fix
Check the existing flag before closing:
PHP_RSHUTDOWN_FUNCTION(syslog)
{
if (PG(have_called_openlog)) {
php_closelog();
}
...
}
That keeps the per-request BG(syslog_device) cleanup, closes the handle when this request opened it, and leaves a host-owned handle alone.
Version
PHP 8.5.11, and the same code is in the current PHP-8.5 and master branches.
- 主要言語
- C
- スター
- 40.4k
- フォーク
- 8.2k
- 平均マージ
- 2日 9時間
- マージ済み PR(30日)
- 177
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
php/php-src のほかの issue
-
Bug Status: Needs Triage
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
php/php-src#24196 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
Feature Status: Needs Triage
難易度 2/5 1〜3時間 初心者へのやさしさ 73/100
php/php-src#24183 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
Sockets from synchronous stream_socket_client() are left in non-blocking mode on Windows対応中かも このイシューにリンクされたプルリクエストがオープン中、またはマージ済みです。 オープンBug Status: Needs Triage
難易度 2/5 1〜3時間 初心者へのやさしさ 66/100
メンテナーはふだん 1 日以内に返信
-
sapi_lsapi_ub_write does not return bytes written in lsapi mode対応中かも このイシューにリンクされたプルリクエストがオープン中、またはマージ済みです。 オープンBug Status: Needs Triage
難易度 1/5 1時間未満 初心者へのやさしさ 90/100
メンテナーはふだん 1 日以内に返信
-
Bug Status: Needs Triage
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
メンテナーはふだん 1 日以内に返信
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 66/100
FujiNetWIFI/fujinet-lib#186 ·
メンテナーはふだん 1 日以内に返信
-
VIEW_TYPE set for computer players対応中かも @Loobinex が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
メンテナーはふだん 2 日以内に返信
-
bug
難易度 2/5 1時間未満 初心者へのやさしさ 78/100
brunodev85/winlator-app#90 ·