web-dev-qa-db-ja.com

フォーク爆弾でシステムをクラッシュできないのはなぜですか?

最近、私はGNU/Linuxのプロセスに関する情報を掘り下げており、悪名高いフォーク爆弾に遭遇しました。

:(){ : | :& }; :

理論的には、システムがリソースを使い果たすまで無限に複製することが想定されています...

ただし、CLI DebianGUI Mintの両方でテストしてみました-)ディストリビューション。システムに大きな影響を与えることはないようです。はい、たくさんのプロセスが作成されています。しばらくすると、次のようなコンソールメッセージが表示されます。

bash:fork:リソースが一時的に利用できません

bash:fork:再試行:子プロセスなし

しかし、しばらくすると、すべてのプロセスが終了し、すべてが正常に戻ります。 limitがユーザーあたりのプロセスの最大量を設定していることを読みましたが、実際にはそれを上げることができないようです。

フォークボムに対するシステムの保護は何ですか?すべてがフリーズするか、少なくとも大幅に遅れるまで、なぜ複製しないのですか?フォーク爆弾でシステムを本当にクラッシュさせる方法はありますか?

55
Plancton

おそらく、systemdを使用するLinuxディストリビューションを使用しています。

Systemdはユーザーごとにcgroupを作成し、ユーザーのすべてのプロセスは同じcgroupに属します。

Cgroupsは、プロセスの最大数、CPUサイクル、RAM使用状況など)などのシステムリソースに制限を設定するLinuxメカニズムです。これは、ulimitgetrlimit() syscallを使用)。

systemctl status user-<uid>.slice(ユーザーのcgroupを表す)を実行すると、tasks(プロセスとスレッド)の現在の最大数を確認できますそのcgroup内で許可されます。

$ systemctl status user- $ UID.slice
●user-22001.slice-UID 22001のユーザースライス
ロード:ロード
ドロップイン:/usr/lib/systemd/system/user-.slice.d 
└─10-defaults.conf
アクティブ:2018-09-10月17:36:35 EEST以降アクティブ。 1週間3日前
 タスク:17(制限:10267)
メモリ:616.7M 

デフォルトでは、systemdが各ユーザーに許可するタスクの最大数は、「システム全体の最大」(sysctl kernel.threads-max)の33%です。これは通常、約10,000タスクに相当します。この制限を変更する場合:

  • Systemd v239以降では、ユーザーのデフォルトはTasksMax =で設定されます。

    /usr/lib/systemd/system/user-.slice.d/10-defaults.conf
    

    特定のユーザーの制限を調整するには(すぐに適用され、/ etc/systemd/system.controlに保存されます)、次のコマンドを実行します。

    systemctl [--runtime] set-property user-<uid>.slice TasksMax=<value>
    

    ユニットの設定を上書きする通常のメカニズム(systemctl editなど)もここで使用できますが、再起動が必要になります。たとえば、everyユーザーの制限を変更する場合は、/etc/systemd/system/user-.slice.d/15-limits.confを作成できます。

  • Systemd v238以前では、ユーザーのデフォルトは/etc/systemd/logind.confUserTasksMax =で設定されています。値を変更すると、通常は再起動が必要になります。

これに関する詳細:

85
Hkoof

これにより、最新のLinuxシステムがクラッシュすることはもうありません。

プロセスの蓄積を作成しますが、プロセスがアイドル状態になると、実際にはそれほど多くのCPUを消費しません。現在RAMが不足する前に、プロセステーブルのスロットが不足しています。

Hkoofが指摘するようにcgroupに制限されていない場合でも、次の変更によりシステムがダウンします。

:(){ : | :& : | :& }; :
13
Joshua

90年代に戻って、私は自分でこれらの1つを誤って解き放ちました。 fork()コマンドが含まれているCソースファイルに実行ビットを誤って設定してしまいました。ダブルクリックすると、cshは、希望するようにエディターで開くのではなく、実行しようとしました。

それでも、システムはクラッシュしませんでした。 Unixは十分に堅牢で、アカウントやOSにプロセス制限があります。代わりに何が起こるかは、非常に遅くなり、プロセスを開始する必要があるものはすべて失敗する可能性があります。

舞台裏で起こっていることは、プロセステーブルが新しいプロセスを作成しようとしているプロセスでいっぱいになることです。それらの1つが終了した場合(プロセステーブルがいっぱいであるためにフォークでエラーが発生したため、または絶望的なオペレーターがシステムに健全性を復元しようとしたため)、他のプロセスの1つが新しいプロセスをフォークして埋めますボイド。

「フォークボム」は、基本的に、プロセステーブルをいっぱいに保つという使命における、意図しない自己修復プロセスのシステムです。それを止める唯一の方法は、どういうわけかそれらを一度にすべて殺すことです。

9
T.E.D.