什麼可能導致深度嵌套的 apache prefork 子程序?

什麼可能導致深度嵌套的 apache prefork 子程序?

我在 CentOS(主要是 6.4)上運行帶有 prefork 和 mod_perl 的 apache 2.2.25。最近有一個例子特別失控,剝奪了孩子的孩子的孩子:

<snip>
\_ /usr/sbin/httpd
|   \_ /usr/sbin/httpd
|   |   \_ /usr/sbin/httpd
|   |       \_ /usr/sbin/httpd
|   |           \_ /usr/sbin/httpd
|   |           |   \_ /usr/sbin/httpd
|   |           |       \_ /usr/sbin/httpd
|   |           |       |   \_ /usr/sbin/httpd
|   |           |       \_ /usr/sbin/httpd
|   |           \_ /usr/sbin/httpd
|   \_ /usr/sbin/httpd
|       \_ /usr/sbin/httpd
|       |   \_ /usr/sbin/httpd
|       |   |   \_ /usr/sbin/httpd
|       |   |   |   \_ /usr/sbin/httpd
|       |   |   \_ /usr/sbin/httpd
|       |   \_ /usr/sbin/httpd
|       \_ /usr/sbin/httpd
\_ /usr/sbin/httpd
|   \_ /usr/sbin/httpd
\_ /usr/sbin/httpd
\_ /usr/sbin/httpd
</snip>

同時,盒子記憶體不足(我不確定哪個先出現,是深度分叉還是記憶體耗盡)。

我以前從未見過 apache 這樣做過,而且還沒有縮小原因。我正在調查的兩種可能性是mod_perl 中的記憶體洩漏(或者更確切地說,在我們的程式碼中,由於mod_perl 而持續存在)或允許一些有限的fork 炸彈的安全漏洞(不能fork 掉任意子項,但可以fork 掉額外的子項)阿帕契兒童)。

我不確定什麼會導致 apache 像這樣分叉(編輯我最初提到了關於 Graceful 如何運作的錯誤信念),但我的想法是循環引用類型記憶體洩漏(直接或間接透過使用盒子上的所有可用記憶體)導致某種 mod_perl 混亂,從而導致額外的工作人員子項是從子項而不是主要父項分叉出來的。我沒有真正的理由這樣做,只是試圖協調兩個問題(深度分叉和記憶體使用)。

或者,我們可能有一個我需要追蹤的安全漏洞。

有沒有人以前見過 apache 的這種行為並知道解決方案?

答案1

事實證明,這是 mod_perl 下的程式碼分叉(這已經是一個壞主意),然後由於不清理子進程而使情況變得更糟。在mod_perl下,當你fork時,你不是在fork你的程式碼,而是在fork apache。因此,該子進程將繼續像任何其他分叉的 apache 子進程一樣提供內容,但不會包含在計數中,因此如果您獲得太多實例,則不會被剔除。

相關內容