Linuxには、フォーク爆弾から保護する手段がありますか?


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

Linuxでこのプログラムを実行しましたが、端末に何も出力されず、OSが死んでしまったようです。Linuxには、メモリ不足になる可能性のあるプログラムに対する保護手段がありますか?


2
私は...あなたは多くのディストリビューションは、大規模なスワップパーティションを作成するために与える悪いアドバイスに従わなかった場合の影響ははるかに少ないだろう疑う
R .. GitHubのSTOPはICE手助け

1
「65kに達した後、新しいプロセスを作成しない」は、対策としてカウントされますか?;)
ボビー

回答:


18

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

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

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

そもそもこれが発生するのを防ぐ1つの方法は、ユーザープロセスの数を制限するulimit -uことです(Bashを使用していると仮定します。他のシェルには同等のものがあります)。


2
注意すべきことの1つは、ulimitbashに固有のことです。他のシェルにはおそらく同じ組み込みコマンドがありますが、名前が異なる可能性があります。
ジェイ

@ジェイ:フェアポイント。私は今の答えでそれを指摘しました、ありがとう!
オリバーチャールズワース

1
ユーザーごとにメモリ/ファイル記述子を制限するだけで十分です。ユーザーごとのメモリを制限することは常に良い考えです。プロセスは(OOM)殺された場合BOFHは、ユーザーのw /システムオフすべての属するプロセス「ローグ」を起動することができるように、ウォッチドッグは、通知を送信する必要があります

ログインパラメーターを介していくつかの制限を設定することもできると信じています
-p_l

10

はい。ただし、システムでデフォルトで有効になっていない場合があります。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 設定可能な制限が他にもいくつかあることを示します(興味深いのは、ユーザーが使用するファイル記述子の最大数です)。


7

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

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


1
+1:cgroupは本当に新しく、ほとんどの人はまだそれらについてあまり知りません。どこでもっと学ぶことができますか?
ケンブルーム

1
@KenBloom:1.ブラウジングによる/sys/fs/cgroup/2. Googleでの検索による3.ブラウジングによるmake menuconfig4.による調査/usr/src/linux/Documentation/cgroups5. systemdドキュメントの閲覧による。申し訳ありませんが、これ以上のお手伝いはできませんが、これらのリソースのみを使用しました。デスクトップでcgroupを使用してリソースを制御しました。
マチェイピエチョトカ

6

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

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

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


1

ここでの最新の回答は3年以上前のものなので、新しいカーネル(4.3以降)は、新しい「PIDsサブシステム」を介してフォーク爆弾を防ぐための明示的なサポートがあることを指摘したいと思います。(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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.