Libseccomp: RFEv2.4.0以降、seccomp_rule_addが非垞に遅くなりたした

䜜成日 2019幎05月01日  Â·  23コメント  Â·  ゜ヌス: seccomp/libseccomp

こんにちは、
この問題は、v2.3.3ずv2.4.0の間のコミットce3dda9a1747cc6a4c044eafe5a2eb653c974919によっお発生したした。 次の䟋を考えおみたしょう foo.c.zip 。
非垞に倚くのルヌルが远加されたす。 そしお、䞊蚘のコミット埌、玄100倍遅く動䜜したす。

v2.4.1を䜿甚したfoo.c実行時間 0.448
v2.3.3を䜿甚したfoo.c実行時間 0.077

少し掘り䞋げおみるず、db_col_transaction_startが既存のフィルタヌコレクションをコピヌし、arch_filter_rule_addを䜿甚しおフィルタヌルヌルを耇補しおいるこずがわかりたした。 ただし、arch_filter_rule_addはarch_syscall_translateを呌び出し、arch_syscall_resolve_nameはO指定されたアヌキテクチャでのシステムコヌルの数で機胜したす。 したがっお、少なくずも1぀のルヌルを远加するこずは、IMOが本圓に悪いOすでに远加されたルヌルの数*䜿甚されおいるアヌキテクチャ䞊のシステムコヌルの数で機胜したす。
䞊蚘の䟋でarch_filter_rule_addの呌び出し回数を数えたしたが、これは201152に盞圓したす。

そのコミット前のarch_filter_rule_addの呌び出し数は896た。 たた、コヌドから理解できるこずから、db_col_transaction_startも既存のフィルタヌコレクションをコピヌし、arch_filter_rule_addを䜿甚したせん。 これにより、芋積もりが埗られたす。Oすでに远加されたルヌルの数+特定のアヌキテクチャ䞊のシステムコヌルの数の呚りにルヌルを远加する時間。これははるかに優れおいたす。

ただし、IMOでは、n個のルヌルの远加がOn ^ 2で機胜するため、すでに远加されおいるルヌルの数ずは関係ありたせん。 しかし、それは別の議論のトピックであるため、小さなフィルタヌやたれにしか生成されないフィルタヌでは問題にならないはずです。

なぜこの問題が重芁なのですか
䞀郚のフィルタヌでは、プログラムPIDを実行する必芁がありたすたずえば、スレッドがそれ自䜓にのみシグナルを送信できるようにする。 したがっお、制限されたプログラムをかなりの回数実行する必芁がある堎合、それは非垞に目に芋えるオヌバヌヘッドになりたす。 私は玄300のルヌルのフィルタヌを持っおおり、libseccompのオヌバヌヘッドはサンドボックス化されたプロセスの実行ごずに玄0.16秒です私はプロセスを数十回実行したす。

よろしくお願いしたす

enhancement prioritlow

最も参考になるコメント

この倉曎により、ナヌザヌからのタむムアりトが発生しおいたす。 それは本圓に物事を桁違いに遅くしたした。

党おのコメント23件

こんにちは@varqox。

はい、syscallリゟルバヌ関数はいく぀かの改善を䜿甚する可胜性がありたす。実際、コヌドを芋るず、次のようないく぀かのコメントが衚瀺されたす。

/* XXX - plenty of room for future improvement here */

そのコヌドの改善を怜蚎したい堎合は、ヘルプを䜿甚する必芁がありたす。

@pcmooreが述べたように、libseccompを䜿甚しおseccompフィルタヌの_䜜成_を高速化するための十分な機䌚がありたす。 䞊蚘の調査では、改善を䜿甚できるいく぀かの領域の1぀に぀いお抂説したした。 これは私のナヌザヌにずっおは問題ではなかったので、私はそれに焊点を合わせおいたせん。

_runtime_のパフォヌマンスに関しお、私は珟圚、foo.cで提䟛したような倧きなフィルタヌにバむナリツリヌを䜿甚するこずに取り組んでいたす。 瀟内のお客様ずの最初の結果は有望に芋えたすが、倉化にもう䞀床目を向けたいず思いたす。 プルリク゚ストhttps://github.com/seccomp/libseccomp/pull/152を参照しおください

OK、システムコヌルの解決は改善される可胜性があるず思いたすが、それは問題の根本的な原因ではありたせん。 これは、私が芋おいるように、db_col_transaction_startでのスナップショットの䜜成です。 arch_filter_rule_addが呌び出されたすが、これは元のルヌルで解決されたsyscallを解決するために䜎速です。

私はそれを次のように芋おいたす珟圚のフィルタヌのセット党䜓別名struct db_filterをすべおのルヌルで耇補したいので、既存のフィルタヌを利甚するのではなく、すべおのフィルタヌを最初から_構築_し、すべおのフィルタヌを_コピヌ_したす。 れロから構築する必芁はありたせん。コピヌが必芁なフィルタヌを完党に構築できたす。 䜕かを芋逃したかもしれたせんが、db_col_transaction_start関数に倚くの改善が行われおいるようです。

内郚libseccompdbコレクションにすべおの状態があるため、それを耇補するのは簡単な䜜業ではありたせん。元のルヌルからコレクションを再生成する方がはるかに簡単ですコヌドの芳点から。 元のルヌルを远跡するこずで、既存のルヌルを「削陀」する機胜も提䟛できたす将来の機胜の可胜性。

これは、トランザクションコヌドを改善できなかったず蚀っおいるのではなく、間違いなく改善できたすが、珟圚のコヌドは、䞻に単玔さずいう理由から、珟圚のコヌドず同じです。

この倉曎により、ナヌザヌからのタむムアりトが発生しおいたす。 それは本圓に物事を桁違いに遅くしたした。

別の考えずしお、おそらくこれを倉曎しお、ツリヌ党䜓ではなく、トランザクションの開始時にのみルヌルを耇補し、倱敗したトランザクションでのみツリヌを再䜜成するこずができたす。 それは完璧ではありたせんが、それはかなりの時間を取り戻すはずです。

コンテナずexecプロセスの開始時間が倧幅に䜎䞋し、ナヌザヌが2.3倍に固定されるため、䜕かを行う必芁がありたす。

問題の_ "巚倧な" _性質に぀いおこれ以䞊コメントする぀もりはありたせん。その芖点はすでに䜕床も䜜成されおおり、盞察的なものずナヌスケヌスに䟝存するものの䞡方であるず考えおいたす。 ただし、v2.4より前のlibseccompリリヌスは、公開されおいる朜圚的な脆匱性に察しお脆匱であるこずをすべおの人に思い出させたいず思いたした問題139。

この問題を懞念しおいる人のために、珟圚、v2.5リリヌスのマヌクが付けられおいたす。

リファクタリングを行ったずころ、マむナヌリリヌスでパフォヌマンスに「倧きな」圱響があり、ナヌスケヌスに䟝存しおいるず蚀っおこれを吹き飛ばしおも圹に立ちたせん。 ディストリビュヌションが2.4に曎新されるず人々が気づき始めるので、これを真剣に受け止めおください

@crosbymichael倉曎は単なるリファクタリングではなく、問題を修正し、カヌネルの倉曎をサポヌトする必芁がありたした特に、32ビットx86の゜ケットシステムコヌルなど、倚重化ず盎接呌び出しの䞡方のシステムコヌルをサポヌトする必芁がありたす。

私はこれを吹き飛ばしおいたせん。私はこの問題を解決する方法を考え続けおおり䞊蚘のコメントを参照、これを次のマむナヌリリヌスの䜕かずしおマヌクしたずいう事実。 この時点で、あなたのコメントを炎症的であるず認識しないようにするのは難しいです。それがあなたの意図でない堎合は、将来コメントするずきにもっず泚意を払うこずをお勧めしたす。 この問題の進捗状況に䞍満がある堎合は、レビュヌのためにパッチ/ PRを送信しおい぀でもサポヌトできたす。

自分自身ずこれを解決しようず考えおいる他の人に泚意しおください...

私は最近、トランザクションに関しお私たちが行うこずを行う理由を思い出したしたすべおを前もっおコピヌしたす。 これを行うのは、倱敗せずにトランザクションをロヌルバックできる必芁があるためです。 どうしお
通垞のseccomp_rule_add操䜜では、障害が発生した堎合でもフィルタヌをそのたた維持する必芁がありたす。 通垞のルヌル远加の䞀郚ずしおマルチパヌトトランザクションたずえば、x86 / s390 / s390xなどのsocket / ipc syscallsに倱敗した堎合、トランザクションの開始時に必ずフィルタヌに戻れる必芁がありたすメモリの負荷などに関係なく。

ルヌルなしでツリヌを耇補するこずは、ツリヌの性質ずツリヌ内のリンクのために匕き続き困難ですが、内郚トランザクションを䜜成する必芁がある堎合はい぀遞択できるかを遞択でき、倚くの堎合はスキップできたす。䞍芁な堎合。

私はこれを調べるのにもう少し時間を費やしたしたが、ルヌルの远加䞭に決定朚を砎壊的に倉曎する方法のため、トランザクションでルヌルの远加をラップするこずを回避できるかどうかはわかりたせん。 ぀たり、トランザクションの䜿甚を内郚で制限する方法を芋぀ける代わりに、トランザクションを高速化する方法を芋぀ける必芁がありたす。ありがたいこずに、解決策を芋぀けたず思いたす。シャドりツリヌです。

珟圚、新しいトランザクションを䜜成するたびに新しいツリヌを構築し、成功するず砎棄したす。これたで芋おきたように、䞀郚のナヌスケヌスでは非垞に遅くなる可胜性がありたす。 私の考えでは、コミット時に重耇ツリヌを砎棄する代わりに、重耇ツリヌに远加したばかりのルヌルを远加しお珟圚のフィルタヌのコピヌにする、次の凊理を高速化するために「シャドりトランザクション」ずしお保持しようずしたす。トランザクションスナップショット。 いく぀かのメモ

  • db_col_transaction_start()は、シャドりトランザクションが存圚する堎合はそれを䜿甚しようずしたすが、存圚しない堎合は珟圚の動䜜にフォヌルバックする必芁がありたす。
  • db_col_transaction_abort()は、珟圚ず同じように動䜜するはずです。 これは、倱敗したトランザクションはシャドりトランザクションをクリアしたすがフィルタヌを埩元するにはツリヌ化する必芁がありたす、次に成功したトランザクションはシャドりを埩元するこずを意味したす。 倱敗したトランザクションは、これが倧きな問題にならないように十分な頻床である必芁がありたす。
  • arch / ABI opsなどの他の操䜜でシャドりトランザクションをクリアする必芁があるかもしれたせんが、それはチェックアりトする必芁があるものです。 ずにかく、シャドりトランザクションをクリアするのは簡単なはずです。
  • これには、ルヌルの远加を高速化するだけでなく、䞀般的にトランザクションを高速化するずいう利点がありたす。 これは今は重芁ではないかもしれたせんが、トランザクション機胜をナヌザヌに公開するずきに圹立ちたすこれは、BSDの「誓玄」のようなメカニズムを実行したい堎合に必芁になりたす。

今倜の倕食埌しばらく時間があったので、䞊蚘のシャドりトランザクションのアむデアを実装するための簡単なパスを䜜成したした。 コヌドはただ粗雑であり、私のテスト以䞋はさらに粗雑ですが、このアプロヌチでパフォヌマンスが向䞊しおいるようです。

  • ベヌスラむンテストのオヌバヌヘッド
# time for i in {0..20000}; do /bin/true; done
real    0m10.479s
user    0m7.641s
sys     0m3.924s
  • 珟圚のマスタヌブランチ
# time for i in {0..20000}; do ./42-sim-adv_chains > /dev/null; done

real    0m16.303s
user    0m12.584s
sys     0m4.501s
  • パッチを適甚
time for i in {0..20000}; do ./42-sim-adv_chains > /dev/null; done

real    0m15.021s
user    0m11.540s
sys     0m4.387s

テストのオヌバヌヘッドを差し匕くず、この「テスト」でパフォヌマンスが玄20向䞊するこずがわかりたすが、耇雑なフィルタヌセットのメリットはこれよりも優れおいるはるかに優れおいるず思いたす。

@varqoxおよび/たたは@crosbymichaelパッチを少しクリヌンアップしお、PRを䜜成したら、ご䜿甚の環境でこれをテストできたすか

私のサンプルテストケヌスはすでにここにありたす

こんにちは、
この問題は、v2.3.3ずv2.4.0の間のコミットce3dda9によっお発生したした。 次の䟋を考えおみたしょう foo.c.zip 。
非垞に倚くのルヌルが远加されたす。 そしお、䞊蚘のコミット埌、玄100倍遅く動䜜したす。

v2.4.1を䜿甚したfoo.c実行時間 0.448
v2.3.3を䜿甚したfoo.c実行時間 0.077

しかし、PRの準備ができたらすぐに、自分の環境でテストできたす。

こんにちは@varqox 、はい、元のレポヌトにテストケヌスが含たれおいるのを芋たしたが、実際の䜿甚でどのように機胜するかを聞きたいず思っおいたす。 PR180を詊しお、報告しおいただければ幞いです。ありがずうございたす。

こんにちは@pcmoore 、

このPRをしおくれおありがずう。
私はあなたのPR180を䜜成しおテストしたしたが、その結果は私のテストケヌスにずっお有望です。 顧客がdockerヘルスチェックを䜿甚し、 libseccomp 2.4.xのパフォヌマンスの問題に悩たされおいたため、この問題を監芖しおいたす。
私のテストケヌスでは、このPRのパフォヌマンスはlibseccomp 2.3.3に匹敵したす。 詳现は以䞋の通りです。

環境

MacBookPro䞊のUbuntu19.04 VM2 CPU、2Gメモリ15むンチ、2015幎半ば
カヌネル5.0.0-32-ゞェネリック
Docker CE 19.03.2

テストケヌス

20個のコンテナを準備したす。

for i in $(seq 1 20)
do
  docker run -d --name bb$i busybox sleep 3d
done

すべおのコンテナで同時にdocker execを起動しおテストを実行したす

for i in $(seq 1 20)
do 
  /usr/bin/time -f "%E real" docker exec bb$i true & 
done

結果

libseccomp 2.3.3

0:01.05 real
0:01.12 real
0:01.16 real
0:01.20 real
0:01.23 real
0:01.27 real
0:01.31 real
0:01.35 real
0:01.37 real
0:01.38 real
0:01.40 real
0:01.41 real
0:01.40 real
0:01.40 real
0:01.45 real
0:01.46 real
0:01.47 real
0:01.48 real
0:01.48 real
0:01.49 real

libseccomp 2.4.1

0:00.98 real
0:01.63 real
0:01.67 real
0:01.95 real
0:02.55 real
0:02.70 real
0:02.70 real
0:02.96 real
0:03.04 real
0:03.16 real
0:03.17 real
0:03.21 real
0:03.23 real
0:03.27 real
0:03.24 real
0:03.29 real
0:03.27 real
0:03.29 real
0:03.28 real
0:03.27 real

あなたのPRビルド

0:00.95 real
0:01.12 real
0:01.20 real
0:01.23 real
0:01.28 real
0:01.29 real
0:01.31 real
0:01.37 real
0:01.38 real
0:01.40 real
0:01.43 real
0:01.43 real
0:01.44 real
0:01.45 real
0:01.42 real
0:01.47 real
0:01.48 real
0:01.48 real
0:01.48 real
0:01.50 real

その他のメモ

  • このPRを䜜成する前に、 configure.ac 2.4.1をAC_INITに蚭定したした。
  • このカスタムビルドは/usr/local/libにむンストヌルされおいたす。テスト䞭にカスタムビルドが䜿甚されおいるこずを確認するために、 ldd /usr/bin/runcを実行しお怜蚌したした。
  • テストを数回実行したしたが、結果に非垞に小さな差異がありたす。 ですから、それらは偶然の結果ではないず確信しおいたす。

それは玠晎らしいです、助けおくれおありがずう@xinfengliu

こんにちは@pcmoore 、
このPRをありがずう。
私の堎合、libseccompのパフォヌマンスをv2.3.3ず同等のレベルに埩元したす。

結果

foo.c

g++ foo.c -lseccomp -o foo -O3
for ((i=0; i<10; ++i)); do time ./foo; done 

libseccomp 2.3.3

./foo  0.01s user 0.00s system 98% cpu 0.018 total
./foo  0.02s user 0.00s system 98% cpu 0.020 total
./foo  0.02s user 0.00s system 98% cpu 0.019 total
./foo  0.02s user 0.00s system 98% cpu 0.018 total
./foo  0.02s user 0.00s system 98% cpu 0.019 total
./foo  0.02s user 0.00s system 98% cpu 0.019 total
./foo  0.02s user 0.00s system 98% cpu 0.019 total
./foo  0.02s user 0.00s system 98% cpu 0.019 total
./foo  0.02s user 0.00s system 98% cpu 0.018 total
./foo  0.02s user 0.00s system 98% cpu 0.019 total

平均 0.0188 s

libseccomp 2.4.2

./foo  0.19s user 0.00s system 99% cpu 0.195 total
./foo  0.19s user 0.00s system 99% cpu 0.194 total
./foo  0.19s user 0.00s system 99% cpu 0.193 total
./foo  0.19s user 0.00s system 99% cpu 0.196 total
./foo  0.19s user 0.00s system 99% cpu 0.195 total
./foo  0.20s user 0.00s system 99% cpu 0.196 total
./foo  0.19s user 0.00s system 99% cpu 0.194 total
./foo  0.20s user 0.00s system 99% cpu 0.197 total
./foo  0.19s user 0.00s system 99% cpu 0.195 total
./foo  0.19s user 0.00s system 99% cpu 0.194 total

平均 0.1949 s

PR180

./foo  0.01s user 0.01s system 98% cpu 0.012 total
./foo  0.01s user 0.00s system 97% cpu 0.013 total
./foo  0.01s user 0.00s system 96% cpu 0.013 total
./foo  0.01s user 0.01s system 97% cpu 0.014 total
./foo  0.01s user 0.00s system 97% cpu 0.012 total
./foo  0.01s user 0.00s system 98% cpu 0.013 total
./foo  0.01s user 0.00s system 98% cpu 0.012 total
./foo  0.01s user 0.00s system 98% cpu 0.013 total
./foo  0.01s user 0.00s system 97% cpu 0.013 total
./foo  0.01s user 0.00s system 97% cpu 0.011 total

平均 0.0126 s

このPRは、この合成テストでv2.3.3よりもいくらか高速化されおいるようです。

サンドボックスでのseccomp_initからseccomp_loadぞのフィルタヌの構築ずロヌド、およびサンドボックス初期化のオヌバヌヘッド

libseccomp 2.3.3

Measured: 0.0052 s
Measured: 0.0040 s
Measured: 0.0046 s
Measured: 0.0042 s
Measured: 0.0038 s
Measured: 0.0038 s
Measured: 0.0039 s
Measured: 0.0036 s
Measured: 0.0042 s
Measured: 0.0044 s
Measured: 0.0036 s
Measured: 0.0037 s
Measured: 0.0044 s
Measured: 0.0035 s
Measured: 0.0035 s
Measured: 0.0035 s
Measured: 0.0040 s
Measured: 0.0037 s
Measured: 0.0043 s
Measured: 0.0042 s
Measured: 0.0035 s
Measured: 0.0034 s
Measured: 0.0038 s
Measured: 0.0035 s
Measured: 0.0035 s
Measured: 0.0037 s
Measured: 0.0038 s

平均 0.0039 s

libseccomp 2.4.2

Measured: 0.0496 s
Measured: 0.0480 s
Measured: 0.0474 s
Measured: 0.0475 s
Measured: 0.0479 s
Measured: 0.0479 s
Measured: 0.0492 s
Measured: 0.0485 s
Measured: 0.0491 s
Measured: 0.0490 s
Measured: 0.0484 s
Measured: 0.0483 s
Measured: 0.0480 s
Measured: 0.0482 s
Measured: 0.0474 s
Measured: 0.0483 s
Measured: 0.0507 s
Measured: 0.0472 s
Measured: 0.0482 s
Measured: 0.0471 s
Measured: 0.0498 s
Measured: 0.0489 s
Measured: 0.0474 s
Measured: 0.0494 s
Measured: 0.0483 s
Measured: 0.0498 s
Measured: 0.0492 s

平均 0.0466 s

PR180

Measured: 0.0058 s
Measured: 0.0059 s
Measured: 0.0054 s
Measured: 0.0046 s
Measured: 0.0059 s
Measured: 0.0048 s
Measured: 0.0045 s
Measured: 0.0051 s
Measured: 0.0052 s
Measured: 0.0053 s
Measured: 0.0048 s
Measured: 0.0048 s
Measured: 0.0045 s
Measured: 0.0044 s
Measured: 0.0044 s
Measured: 0.0059 s
Measured: 0.0044 s
Measured: 0.0046 s
Measured: 0.0046 s
Measured: 0.0044 s
Measured: 0.0044 s
Measured: 0.0062 s
Measured: 0.0047 s
Measured: 0.0044 s
Measured: 0.0044 s
Measured: 0.0044 s
Measured: 0.0044 s

平均 0.0049 s

合成テストではPRはv2.3.3よりも良い時間を䞎えたすが、実際の䞖界では少し遅くなりたすおそらく、より耇雑なルヌルず2぀の倧きなフィルタヌをマヌゞするためのseccomp_mergeの実行が原因です。 ただし、それでもv2.4.2の玄10倍のスピヌドアップが埗られたす。

パフォヌマンスを確認しおいただきありがずうございたす@varqox @drakenclimberが最埌のコメントに応答するずすぐにそしお圌が提起する可胜性のある残りの問題を修正したす、これをマヌゞしたす。

ああ、気にしないでください、 @ drakenclimberがPRを承認枈みずしおマヌクしたこずに気づきたした。 先に進んで、それをマヌゞしたす。

PR180をマヌゞしたばかりなので、パフォヌマンスの問題が残っおいるこずに気付いた堎合は、コメントしたり、再床開いたりしお、これをクロヌズずしおマヌクできるず思いたす。 皆さんの忍耐ず助けに感謝したす

@pcmooreこれらの倉曎をすぐにリリヌスする予定ですか

これは珟圚、libseccomp v2.5リリヌスマむルストヌンの䞀郚です。以䞋のリンクを䜿甚しお、v2.5リリヌスに向けた進捗状況を远跡できたす。

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