10

C# プログラムで lua をサポートするために lua インターフェイスを使用しています。ユーザーがこのようなコードを送信すると、ワーカー スレッドがフリーズします。

while true do end

無限ループが実行されているかどうかを検出する方法はありますが、ワーカー スレッドから DoString メソッドを終了する適切な方法が必要です。何か案は?

編集:@kikito、はい、私はそれをそのようなものだと思っています。私が抱えている問題は、DoString メソッドを強制終了するクリーンな方法が見つからないことです。Lua インターフェイスのメイン クラス (Lua) にはいくつかの静的な依存関係があるように見えlua.Close();ます。次にluaクラスをインスタンスnew Lua();化すると、保護メモリについて何か言ってクラッシュします

編集: 私の .Close コードを示すフィーチャー ブランチ https://github.com/AndersMalmgren/FreePIE/tree/detect-and-recover-infite-lua-loop

4

6 に答える 6

9

サンドボックス ルア

フックを設定するだけでは、意図しないリソースの浪費を防ぐにはまったく不十分であり、乱用は言うまでもありません。簡単な例を次に示します (文字列パターン マッチング中に時間が費やされます。デバッグ フックは呼び出されません)。

s=('a'):rep(20000):match('.-b')

Lua コードの一部に時間/メモリの制約を強制する唯一の確実な方法は、Lua インタープリターを独自のプロセスで実行し、OS にそのプロセスを監視させることです。

Lua の優れた点は、サンドボックス化のために複雑な OS 依存のパーミッション設定が必要ないことです: 時間とメモリを制限するだけです (合理的です; Windows にはJob Objectsがあり、Unix には ulimits 関連があります: Linux リソース制限) および次に、os.execute、io-library の半分、luasocket などのモジュールなどをスクリプターから遠ざけます (非常に簡単です)。

サンドボックス化されたコードのエラーからの回復

Lua インタープリターを破棄することなく、ほとんどすべて (時間/メモリ制限の違反を除く) を処理できます。ユーザーが指定したコードの実行をpcall内にラップするだけです。自分で失敗する可能性のある Lua-API 関数を呼び出す場合は、それらを pcall できる関数内にラップする必要があります (または、Lua パニック関数を設定して、そこから処理します)。


[このスレッドをちらりと見て、debug.sethook がサンドボックス化に適していると思い込ませたくありませんでした。また、stackoverflow では (まだ) コメントできません]

于 2012-09-24T23:38:30.260 に答える
0

他のLuaエラーと同じように処理することをお勧めします。言い換えれば、ユーザーが書いたばかりのように上記のコードを脅かす

error("Script execution has been cancelled after stalling for too long")

(スクリプトの実行に一定の時間がかかることはないと想定して、無限ループを検出すると想定しています。そうでない場合は、メッセージを適切に変更してください)

これを処理する方法は、Luaエラーをどのように処理するかによって異なりますが、とにかく処理する必要があるため、ほとんどのコードがすでに存在している可能性があります。

編集:マーティンジェームズの提案があなたの最良の選択肢のようです。debug.setHook()を使用して、100 Lua命令ごとにいくつかのluaコードを実行できます。同じクライアントコードで時間が経過しすぎると、エラーがスローされます。これに関する詳細は、このメーリングリスト、およびlua-projectリポジトリのコードサンプルに記載されています。

于 2012-04-27T22:00:19.043 に答える
0

この問題に対処するために、2 つの手法を使用しました。1 つ目は、別のタスク内で DoFile または DoString メソッドを呼び出すことです。そうすれば、スレッドを中止できます。インタープリターを終了するためのテクニック(フック内など)については知りません。

別の方法は、別のAppdomainをセットアップすることです。これを使用して、個別の制約 (証拠と許可セット) を設定することもできます。詳細については、 CreateDomainを参照してください。

于 2014-09-17T19:05:57.710 に答える