Hacktoberfest 2026:維護者為十月標記出來的 issue,仍然開放、適合新手。 瀏覽 Hacktoberfest issue

standard/syslog: the request shutdown hook calls closelog() even when the request never opened syslog

未關閉 適合新手
#24,308 0 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

維護者通常 1 天內回覆

還沒有人認領這個 Issue。

評估

難度
2/5
預估耗時
半天
新手友好度
62/100
Issue 類型
缺陷
描述清晰度
描述清楚
活躍度
活躍
技術堆疊
c
領域
backend

研究方向

無條件關閉位於 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 的請求會跳過 php_closelog(),同時仍釋放 BG(syslog_device)。依 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 天 24 分鐘
30 天內合併 PR
157

環境準備

  • 沒有 Dockerfile 或 Docker Compose 檔案
  • 沒有 Pull Request 範本
  • 閱讀貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

php/php-src 的其他 Issue

查看 php/php-src 的全部 Issue

相似的 Issue

更多 C Issue

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。