Libseccomp: バグopenmpずの互換性

䜜成日 2017幎09月02日  Â·  19コメント  Â·  ゜ヌス: seccomp/libseccomp

マルチスレッドの非決定論的な性質により、これをデバッグするのは困難ですが、私はかなり再珟性のあるテストケヌスseccomp_omp.c.gzに到達したず思いたす。 -O0 -ggdb -fopenmpおプログラムをコンパむルしたす。

1぀のスレッドだけで実行し、犁止されおいるsyscallを実行させるず、プログラムは期埅どおりに終了したす。

$ ./seccomp_omp -t 1 -k 0      
86195973
[1]    10103 invalid system call (core dumped)  ./seccomp_omp -t 1 -k 0

ただし、スレッドが増えるず、機胜しなくなりたす。

$ ./seccomp_omp -t 2 -k 0
86198868
86195973
86200317
^C

プログラムは殺されるこずはなく、䜕もするのをやめるだけです。 SIGSYSシグナルに䜕が起こったのか、そしおなぜそれが凊理されないのか、私は途方に暮れおいたす。

これはlibseccompの問題ではないかもしれたせんが、私はseccomp、シグナル、およびスレッドシステム党般に぀いお、根本的な原因をデバッグするのに十分な知識がありたせん。 あなたがそれを理解できるこずを願っおいたす。

bug prioritmedium

党おのコメント19件

泚私はただあなたのテストケヌスを芋おいたせん、私はあなたのよく曞かれた説明に基づいお掚枬しおいたす

これのマルチスレッドの性質を考慮しお、カヌネルにフィルタヌをロヌドする前に、 SCMP_FLTATR_CTL_TSYNCフィルタヌ属性をtrueに蚭定しおみたしたか

スレッドに分割する前にseccompフィルタヌを远加したため、 SCMP_FLTATR_CTL_TSYNC蚭定したせんSCMP_FLTATR_CTL_TSYNCを远加しおも、違いはありたせんこれは、ペダンティック゚ラヌ凊理で100行未満です。

さお、私はそれに぀いお蚀及したかっただけです。 正しく実行しおいるようです新しいスレッドを生成する前にフィルタヌを蚭定したす。 よく芋る必芁がありたすが、すぐにそれを行う機䌚がないかもしれたせん。

私が露骚に間違ったこずをしおいないずいう確認は私にずっお十分です。 ゆっくりしおください

シングルスレッドの䟋./seccomp_omp -t 1 -k 0では、openmpはシングルスレッドのみが実行されるこずを認識しおいるため、openmpはマルチスレッドのforルヌプで通垞行う同期の倚くをバむパスしたす。 カヌネルのseccomp_run_filtersで凊理されたシステムコヌルを芳察するこずでこれを確認したした。 予想通り、__ NR_writeの呌び出しず__NR_madviseの呌び出しがあり、seccompがカヌネルにスレッドを匷制終了するように指瀺したした。

マルチスレッドの䟋./seccomp_omp -t 2 -k 0では、openmpはforルヌプを䞊列化しようずしたす。 したがっお、openmpラむブラリの倚くが利甚されたす。 これは、seccomp_run_filtersを介しおシステムコヌルを再床監芖するずきに明らかになりたす。 __NR_mmap、__ NR_mprotect、__ NR_clone、__ NR_futex、およびその他のsyscallは、madviseを呌び出す前に呌び出されたす。 最終的に、2぀のスレッドのうちの1぀が最終的にmadviseを呌び出し、seccompがそのスレッドを適切に匷制終了したす。 しかし、openmpはスレッド間で同期を取り、2番目のスレッドがmadviseを呌び出すそしお匷制終了する前に、2番目のスレッドはデッドスレッドからの䜕かを埅機しおいるずきにfutexを呌び出したす。 そしお、これがプログラムがハングする理由です。 1぀のスレッドが匷制終了され、2番目のスレッドはデッドスレッドからのデヌタが到着しないのを埅っおいたす。

私は、OpenMPでずっず働いおいたが、いく぀かの議論[があるように思われおいない1 、 2 、 3䞊列ブロック内の信号で、...]。 最終的には、避けるのが最善の難しい問題のように芋えたす。

いく぀かの朜圚的な簡単な解決策があるようです

  1. デフォルトのハンドラヌずしおSCMP_ACT_KILLを䜿甚しないでください。 代わりに、代わりに゚ラヌコヌドを䜿甚するように切り替えたす䟋 SCMP_ACT_ERROR(5) 。 サンプルプログラムでこの倉曎を行い、正しく終了するこずを確認したした。

  2. openmpの機胜が必芁ない堎合は、pthread_createやforkなどのより䞀般的な゜リュヌションの䜿甚に切り替えるこずもできたす。

@drakenclimberなので、問題は実際にはopenmpが远加のシステムコヌルを䜜成しおいるだけのように聞こえたすが、通垞はフィルタヌの䞀郚ではない可胜性がありたすか それずも、より倧きなポむントが欠けおいたすか

@drakenclimberお時間を

より倚くのコンテキストを䞎えるために私は科孊的なコヌドを曞いおいるので、OpenMPで物事をシンプルに保぀のが奜きです。 ただし、ナヌザヌを自分自身から保護したいずも思っおいたす。 したがっお、私のプログラムが異垞なこずをした堎合は、それを無効にするだけです。 私が最終的に達成したいのは、プロセス96をやや劥圓な゚ラヌメッセヌゞで匷制終了するこずだず思いたす。

私はではerrnoに䜿甚する必芁がありたすどのような倀SCMP_ACT_ERROR密接に暡倣するためにSECCOMP_RET_KILL_PROCESS  すべおのシステムコヌルで正垞に機胜するものはありたすか

@ pcmoore-ちょっず。 しかし、より倧きな問題は、openmpが䞊列構造内でシグナルを適切に凊理しないこずだず思いたす。 これは仕様によるものだず思いたす。

@ kloetzl-心配ありたせん

ctx = seccomp_init(SCMP_ACT_ERRNO(ENOTBLK));
...
bool kill_process = false;
int rc;
#pragma omp parallel for num_threads(THREADS)
  for (int i = 0; i < THREADS * 2; i++) {
    fprintf(stderr, "%u\n", func(i));
    if (i == K) {
      rc = madvise(NULL, 0, 0); 
      if (rc < 0)
        kill_process = true;
      }   
    // sleep(10);
  }

  if (kill_process)
    goto error;

  seccomp_release(ctx);
  return 0;
error:
  seccomp_release(ctx);
  return -1; 
}

errnoがSCMP_ACT_ERRNO()返す必芁があるかどうかに぀いおは、実際にはあなた次第です。 SCMP_ACT_ERRNO()は、すべおのシステムコヌルで機胜したす。 そしお、あなたのプログラムがそれを凊理し、ナヌザヌに゚ラヌを返すものになるので、あなたはあなたに最適なerrnoを遞ぶこずができたす。 実際、あいたいなものたずえば、 ENOTBLKを遞択するこずは、゚ラヌがseccompが呌び出しをブロックしたこずによるものであるこずを

tl; dr-䞊列ルヌプで問題を怜出したすが、ルヌプが完了するたで問題の凊理を埅ちたす。 システムコヌルが倱敗したため、ルヌプ内に防埡コヌディングを远加する必芁がある堎合がありたす。

@ kloetzl-問題96を調べお、OpenMPでどれだけうたく機胜するかを確認したす。 それもたた別の解決策かもしれたせん。 ありがずう

そしお、あなたのプログラムがそれを凊理し、ナヌザヌに゚ラヌを返すものになるので、あなたはあなたに最適なerrnoを遞ぶこずができたす。 実際、あいたいなものENOTBLKなどを遞択するこずは、゚ラヌがseccompが呌び出しをブロックしたこずによるものであるこずを知る方法である可胜性がありたす。

぀たり、 madviseはmalloc腞の奥深くで呌ばれたす。 したがっお、私ぱラヌを凊理する人ではありたせん、glibcはそうです。 したがっお、問題は、glibcおよびsyscallを実行する他のすべおのラむブラリは、syscallがmanペヌゞに蚘茉されおいる以倖の゚ラヌを返し、適切に凊理できるこずを知っおいたすか

問題は、madviseはmallocの腞の奥深くず呌ばれおいるずいうこずです。 したがっお、私ぱラヌを凊理する人ではありたせん、glibcはそうです。 したがっお、問題は、glibcおよびsyscallを実行する他のすべおのラむブラリは、syscallがmanペヌゞに蚘茉されおいる以倖の゚ラヌを返し、適切に凊理できるこずを知っおいたすか

ああ...お奚め。 確かにglibcコヌドを調べる必芁がありたすが、次の掚枬を危険にさらすこずをいずわないでしょう。

  • madviseが゚ラヌを返す堎合、glibcも_間違いなく_゚ラヌを返したす
  • glibcが返されたseccompずは異なる゚ラヌを返す可胜性があるこずは間違いありたせん。したがっお、 ENOTBLKような「カスタム」リタヌンコヌドを期埅しおいる堎合は泚意が必芁です。

簡単に蚀うず、glibcは_any_゚ラヌコヌドを抑制すべきではありたせんが、代わりに別の゚ラヌコヌドを返す可胜性がありたす

私はあなたたちに远い぀くようにしおいたすが、OpenMPのバックグラりンドが䞍足しおいるために少し遅れおいるのではないかず心配しおいたす...䞊蚘のコメントに基づくず、 KILL_PROCESSはここで実行可胜な解決策になる可胜性がありたすか もしそうなら、v2.4リリヌスの前に察凊すべきこずの私のリストにありたすが、その問題の優先順䜍を䞊げるこずができたす。

@ pcmoore-はい、 KILL_PROCESSはこのバグの実行可胜な解決策だず思いたす。 䞊蚘の@kloetzlのテストプログラムをKILL_PROCESSアクションを䜿甚しおテストしたしたが、ハングは発生しなくなりたした。

私はそれを実装したしたが、珟圚、Pythonの自動テストでいく぀かの問題にぶ぀かっおいたす。 来週パッチを出す必芁がありたす。

@drakenclimberああ、パッチ 私はパッチが倧奜きです:)

みんなありがずう。

KILL_PROCESSで問題が解決したこずを確認できたす。Archでロヌカルバヌゞョンのlibseccompをハッキングしたずころ、テストプログラムが意図したずおりに倱敗したした。 ただし、確実なテストを提䟛し、それらを異なるカヌネルで実行するこずは、より倧きな課題になる可胜性がありたす。

確認@kloetzlをありがずう。

はい、適切なテストを曞くのは面倒ですが、それは重芁です。 IMHOをテストするコヌドず同じくらい重芁です。

@drakenclimberからのPRを楜しみにしおいたす。コヌドが公開されたら、もう少し話し合うこずができたす。

私はいく぀かのCOVID-19春の倧掃陀をしおいたす、そしお私たちはあなたの問題を解決したず思いたす、それは正しい@kloetzlですか この問題をクロヌズしたすが、間違っおいおも問題が解決しない堎合は、お知らせください。再開したす。

思い出させおくれおありがずう、私は自分の偎で少しテストしたした。

この問題はほずんど修正されおいたすが、小さな問題がありたす。 無効なシステムコヌルが発生したずきに、プログラムが途方に暮れるこずはなくなりたした。 SCMP_ACT_TRAPするず、䞍正なシステムコヌルの名前を生成するこずもできたす。 ただし、OpenMPはシグナルハンドラヌを䞊曞きするため、耇数のスレッドが生成されるず、デフォルトの゚ラヌメッセヌゞにフォヌルバックしたす。 ナヌザヌ゚クスペリ゚ンスの芳点から、私はこの動䜜が奜きではありたせんが、それが埗られるのず同じくらい良いず思いたす。

ああ、はい、libseccompでシグナルハンドラが䞊曞きされるこずに぀いお私たちにできるこずがたくさんあるかどうかはわかりたせん。申し蚳ありたせん。

残りの郚分が機胜したこずをお知らせいただきありがずうございたす。

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡