
フォーク爆弾の影響をテストするためにテスト VM をセットアップしました。そこで、ユーザーlimits.conf
向けに次のように編集しました。root
root hard nproc 512
ここで、次のようにフォーク爆弾を投下します。
:(){ :|:& };:
この後、しばらくすると (512 の制限に達するまでかかると思います)、次のエラーが表示されます。
これは止まることなく続きます。マシンを再起動せずにこれを停止する方法はありますか?
答え1
マシンを再起動せずにこれを停止する方法はありますか?
これは不可能というわけではなく、運が良ければ可能です。つまり、別のプロセスが起動される前にすべてのプロセスを終了させるということ です。1 しかし、非常に幸運に恵まれなければならず、信頼性が高く、価値のある努力とは言えません。[たぶん、SLM は私より幸運です、笑 -- 正直に言うと、私はそこまで努力していません]優先順位を変えて試してみると、チャンスは向上する可能性があります (を参照man nice
)。ただし、これによってフォーク爆弾の有効性も損なわれると思われます。
タイムアウトするものを使うのが良いかもしれません。C言語の例については、脚注5を参照してください。私の答えはここにあります2 シェル スクリプトでも同様のことができますが、次のように短くはなりません:(){ :|:& };:
。
#!/bin/bash
export fbomb_duration=$1
export fbomb_start=$(date +%s)
go () {
now=$(date +%s)
if [[ $(($now-$fbomb_start)) -gt $fbomb_duration ]]
then exit 0;
fi
go &
}
while ((1)); do
go
done
これを 1 つの引数 (秒数) で実行します。その時間が経過すると、すべてのフォークが終了します。
1実際、カーネル OOM キラーが幸運に恵まれれば、最終的にはそれがすべて自然に発生する可能性があります。しかし、期待しすぎないでください。
2そこで特定の爆弾を無効化するために使用された方法 ( を設定するvm.overcommit_memory=2
) は、一般的にはほぼ確実に機能しませんが、試してみることはできます。今のところシステムを実行したままにしておきたいので、私は試していません ;)
答え2
この質問に対する回答を作成中に、次のタイトルが付けられました。フォーク爆弾の fork() はどこにありますか :(){ :|: & };:?、私は「ヒューズ遅延フォーク爆弾」と呼ぶものを組み立てました。これは破壊するのが簡単でした。
さらに、その回答を開発している間、すべてのプロセスを強制終了することでフォーク爆弾を定期的に停止することができました。予想していたよりも簡単で再現性がありました。
使用された方法
この回答を書いてからしばらく経っているので、今は 100% 確信はありませんが、思い出す限りでは、次の方法を使用していたと思います。
$ pkill -f :
プロセスを待つために少しの間停止しましたが、最終的には実行できました。また、フォーク爆弾を開始する前に親プロセス ID をメモして、これも実行します。
$ pkill -P <PPID>
これは、フォーク爆弾が実行された親プロセス ID (PPID) です。この方法では、すべての子プロセスが停止し、すべての子プロセスが連鎖的に停止します。
答え3
回答で提案されているようにできると思いますここシェルにアクセスできることを前提としています。
killall -STOP -u user1
killall -KILL -u user1