web-dev-qa-db-ja.com

Linuxには、フォーク爆弾から保護するための対策がありますか?

#include <unistd.h>
int main(int argc, char* argv[]) {
  while(1)
  {
    fork();
  } 
}

このプログラムをLinuxで実行しましたが、ターミナルに何も出力されません。OSが停止しているようです。 Linuxには、メモリ不足になる可能性のあるそのようなプログラムに対する保護手段がありますか?

12
venus.w

これは フォーク爆弾 として知られています。

Linuxには、メモリ不足になる可能性のあるそのようなプログラムに対する保護手段がありますか?

あんまり。各フォークは、独自の仮想アドレス空間とメモリ使用量で新しいプロセスを生成します。したがって、各コピーは比較的小さいです。最終的には、システム上のすべての物理メモリとスワップメモリ​​を使い果たし、メモリ不足(OOM)キラーが個々のプロセスの強制終了を開始します。しかし、フォーク爆弾はそれでも同じくらい速くプロセスを作成します(速くはないにしても)。

そもそもこれが発生しないようにする1つの方法は、 ulimit -u (Bashを使用していると仮定します。他のシェルにも同等のものがあります)。

18

はい。ただし、システムでデフォルトで有効になっていない場合があります。 setrlimitシステムコールは、ユーザーごとのプロセス数を含むシステム制限を定義します。

最初にカーネルAPIでそれを見てみましょう(「linux」について言及したので):setrlimitのマンページを使用できます。これにより、次のようなことを行うように指示されます。

#include <sys/resource.h>
...

struct rlimit  r;

rnew.r_cur = 40;
rnew.r_max = 50;
setrlimit(RLIMIT_NPROC,&r);

これにより、ユーザーあたりの最大プロセス数が設定されます(RLIMIT_NPROC)から40(ソフト制限)および50(ハード制限)。

これで、シェルから、bashを使用する場合、ulimit組み込みコマンドを使用できます。

ulimit -u
29089

引数として渡すことで制限を設定できます。

ulimit -u 100

ulimit --helpは、設定できる他のいくつかの制限があることを示します(興味深いのは、ユーザーが使用するファイル記述子の最大数です)。

10
Jay

ユーザーレベルとシステムレベルのどちらで使用するかによって異なります。ユーザーレベルでは、ulimit(または他のシェルの対応するコマンド)が最も簡単な解決策になります。

ただし、システムレベルでは、悪意のあるユーザー(またはulimitを使用していない)がシステムを停止するのを防ぐメカニズムがあります。 Linux cgroupsメカニズムは、グループごとにリソースを制限できます。強制することができます(pam_systemd machanism)特定のグループに属するユーザーセッション。これには、CPUスケジューラなどの他の利点もあります。

7

Bashシェルの ulimit -u を使用して、「最大ユーザープロセス」に制限を設定します。

Cシェルから、limitコマンドを使用します。

これを行うためにシステムコールが必要な場合は、 setrlimit 呼び出しを使用してRLIMIT_NPROCを設定します。

6
Ken Bloom

ここでの最新の回答は3年以上前のものであるため、新しいカーネル(4.3以降)には、新しい「PIDサブシステム」を介したフォーク爆弾の防止を明示的にサポートしていることを指摘しておきます。 ( https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=49b786ea146f69c371df18e81ce0a2d5839f865c および https:// git。 kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=917d8e2d10f40e28aa9e0d824b2e5b8197d79fc2

1
David Ongaro