Libseccomp: バグ疑䌌システムコヌルのBPFを生成しない

䜜成日 2020幎06月15日  Â·  20コメント  Â·  ゜ヌス: seccomp/libseccomp

問題249、特にこのコメントを参照しおください

実際に生成されたbpfに存圚しないsyscall4294957285をチェックするのはなぜですか

すべきではなく、以前はそうしおいたせんでしたが、珟圚のlibseccompにはバグがあるようです。

このバグを報告しおくれた@ vt-altの功瞟です。

bug prioritmedium

党おのコメント20件

以䞋の改善されたドラフトを優先しお削陀されたリプロデュヌサヌ

明確にするために、デバッグの目的で、PFCで疑䌌システムコヌルを発行する必芁がありたすが、圹に立たないBPFフィルタヌルヌルを発行するべきではありたせん。

レポヌトから問題を䜜成しおいただきありがずうございたす。

明確にするために、デバッグの目的で、PFCで疑䌌システムコヌルを発行する必芁がありたすが、圹に立たないBPFフィルタヌルヌルを発行するべきではありたせん。

これを考え盎しおください。 これは、PFCがBPFを反映しない堎合にのみ、事態を耇雑にし、曖昧にするだろうず私は信じおいたす。

これを考え盎しおください。 これは、PFCがBPFを反映しない堎合にのみ、事態を耇雑にし、曖昧にするだろうず私は信じおいたす。

システムコヌルがPFCにない堎合、ラむブラリが存圚しないシステムコヌルのフィルタヌを远加できなかった方法に぀いお説明する停のバグレポヌトが倚数届きたす。

疑䌌システムコヌルの抂念を理解しおいる人にずっおは、PFC出力からそれらを削陀するのは簡単なこずです。 たた、PFC出力はBPF出力の正確なコピヌを意図したものではなく、単にデバッグツヌルずしお存圚し、生成されたフィルタヌコヌドを芖芚化する簡単な方法ずしお存圚したす。

生成されたフィルタヌコヌドを芖芚化する簡単な方法

ただし、生成されたコヌドには疑䌌システムコヌルが存圚しないため、_生成された_フィルタヌコヌドは芖芚化されたせん。

システムコヌルがPFCにない堎合、ラむブラリが存圚しないシステムコヌルのフィルタヌを远加できなかった方法に぀いお説明する停のバグレポヌトが倚数届きたす。

の論理的な違い条件の有無よりも、疑䌌システムコヌルチェックがコヌドに存圚しおはならないこずを理解する方がはるかに簡単です「最適化された」のように、「アヌチにはそのようなシステムコヌルがないため」。コヌドず実際のコヌドの芖芚化。

PFCの出力ははるかに読みやすいので、 scmp_bpf_disasmを䜿甚するよりもBPFを反映する方がPFCの方が奜きです。

@ vt-altに関するあなたの懞念を理解しおいたす。おそらく将来のリリヌスでは、PFCでそれを行いたすが、PFC出力から疑䌌システムコヌルを削陀するのは間違いだず思いたす。

@drakenclimberこれに぀いお匷い意芋はありたすか

x86_64甚に改蚂されたリプロデュヌサヌ

#include <stdlib.h>
#include <errno.h>

#include <seccomp.h>

#include "util.h"

int main(int argc, char *argv[])
{
        int rc;
        struct util_options opts;
        scmp_filter_ctx ctx = NULL;

        rc = util_getopt(argc, argv, &opts);
        if (rc < 0)
                goto out;

        ctx = seccomp_init(SCMP_ACT_KILL);
        if (ctx == NULL)
                return ENOMEM;

        rc = seccomp_arch_add(ctx, SCMP_ARCH_X32);
        if (rc < 0)
                goto out;

        rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(access), 0);
        if (rc < 0)
                goto out;
        rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(arm_fadvise64_64), 0);
        if (rc < 0)
                goto out;

        rc = util_filter_output(&opts, ctx);
        if (rc)
                goto out;

out:
        seccomp_release(ctx);
        return (rc < 0 ? -rc : rc);
}

曎新TSKIPの問題を修正したした

ただ完党にはテストされおいたせんが、これは修正される可胜性がありたす-これが平衡ツリヌ最適化アルゎリズム@drakenclimberにずっお劥圓であるこずを確認できたすか

diff --git a/src/arch-arm.c b/src/arch-arm.c
index 3465111..4dd4b63 100644
--- a/src/arch-arm.c
+++ b/src/arch-arm.c
@@ -54,7 +54,7 @@ int arm_syscall_resolve_name_munge(const char *name)
        if (sys == __NR_SCMP_ERROR)
                return sys;

-       return sys + __SCMP_NR_BASE;
+       return (sys | __SCMP_NR_BASE);
 }

 /**
@@ -68,7 +68,7 @@ int arm_syscall_resolve_name_munge(const char *name)
  */
 const char *arm_syscall_resolve_num_munge(int num)
 {
-       return arm_syscall_resolve_num(num - __SCMP_NR_BASE);
+       return arm_syscall_resolve_num(num & (~__SCMP_NR_BASE));
 }

 const struct arch_def arch_def_arm = {
diff --git a/src/arch-x32.c b/src/arch-x32.c
index 7b97fb3..3890968 100644
--- a/src/arch-x32.c
+++ b/src/arch-x32.c
@@ -43,7 +43,7 @@ int x32_syscall_resolve_name_munge(const char *name)
        if (sys == __NR_SCMP_ERROR)
                return sys;

-       return sys + X32_SYSCALL_BIT;
+       return (sys | X32_SYSCALL_BIT);
 }

 /**
@@ -57,7 +57,7 @@ int x32_syscall_resolve_name_munge(const char *name)
  */
 const char *x32_syscall_resolve_num_munge(int num)
 {
-       return x32_syscall_resolve_num(num - X32_SYSCALL_BIT);
+       return x32_syscall_resolve_num(num & (~X32_SYSCALL_BIT));
 }

 const struct arch_def arch_def_x32 = {
diff --git a/src/gen_bpf.c b/src/gen_bpf.c
index 55a7958..ae9c3f4 100644
--- a/src/gen_bpf.c
+++ b/src/gen_bpf.c
@@ -1555,6 +1555,10 @@ static int _gen_bpf_syscalls(struct bpf_state *state,
        for (s_iter = s_tail; s_iter != NULL; s_iter = s_iter->pri_prv) {
                if (!s_iter->valid)
                        continue;
+               /* skip pseudo-syscalls */
+               if ((s_iter->num & 0x80000000) &&
+                   (state->attr->api_tskip == 0 || s_iter->num != -1))
+                       continue;

                if (*bintree_levels > 0 &&
                    ((syscall_cnt + empty_cnt) % SYSCALLS_PER_NODE) == 0)

@ vt-altに関するあなたの懞念を理解しおいたす。おそらく将来のリリヌスでは、PFCでそれを行いたすが、PFC出力から疑䌌システムコヌルを削陀するのは間違いだず思いたす。

@drakenclimberこれに぀いお匷い意芋はありたすか

実際にはそうではありたせんが、問題の根本は、PFC出力が耇数の異なる方法で䜿甚されおいるこずだず思いたす。

  1. 䞊蚘のように、これは新しいよりナヌザヌがフィルタヌを倧たかに確認するための簡単な方法です
  2. より䞊玚のナヌザヌは、それが実際のBPFフィルタヌの近䌌倀であるず期埅しおいたす。

おそらく、PFCロゞックに--no-pseudo-syscallsフラグを远加できたすか そうすれば、初心者ナヌザヌにずっおは同じたたですが、䞊玚ナヌザヌはBPFのより良い近䌌を埗るこずができたす。

_UPDATEDTSKIPの問題を修正したした_

ただ完党にはテストされおいたせんが、これは修正される可胜性がありたす-これが平衡ツリヌ最適化アルゎリズム@drakenclimberにずっお劥圓であるこずを確認できたすか

したしょう。 このシナリオを再珟する自動テストを䜜成できるかどうかを確認したいず思いたす。

_UPDATEDTSKIPの問題を修正したした_
ただ完党にはテストされおいたせんが、これは修正される可胜性がありたす-これが平衡ツリヌ最適化アルゎリズム@drakenclimberにずっお劥圓であるこずを確認できたすか

したしょう。 このシナリオを再珟する自動テストを䜜成できるかどうかを確認したいず思いたす。

そしおもちろん、私はあなたが䞊で持っおいる再生噚テストから始めたす。 ありがずう

_UPDATEDTSKIPの問題を修正したした_

ただ完党にはテストされおいたせんが、これは修正される可胜性がありたす-これが平衡ツリヌ最適化アルゎリズム@drakenclimberにずっお劥圓であるこずを確認できたすか

バむナリツリヌは、アキュムレヌタを倉曎する必芁がある堎合に事前に蚈算したす。これにより、 jgeロゞックを挿入するこずがわかりたす。 フィルタの構築䞭に䞊蚘の提案のようにシステムコヌルをダンクアりトするず、このロゞックが壊れたす。

私もただ完党に倉曎をテストしおいたせん:)が、疑䌌システムコヌルを削陀しおバむナリツリヌを機胜させるには、このようなものが必芁になるず確信しおいたす。 私はこれを䜿甚しおBPF二分朚を生成したした、そしおそれは合理的に芋えたす。 本番環境に察応した゜リュヌションに近づいたら、完党に怜蚌したす。

@@ -1532,11 +1532,31 @@ static int _gen_bpf_syscalls(struct bpf_state *state,
                _sys_sort(db_secondary->syscalls, &s_head, &s_tail, optimize);

        if (optimize == 2) {
+               /* since pseudo-syscalls are removed from the filter, we need
+                * to calculate the syscall count by hand
+                */
+               for (s_iter = s_tail; s_iter != NULL; s_iter = s_iter->pri_prv) {
+                       if (!s_iter->valid)
+                               continue;
+
+                       /* skip pseudo-syscalls */
+                       if ((s_iter->num & 0x80000000) &&
+                           (state->attr->api_tskip == 0 || s_iter->num != -1))
+                               continue;
+
+                       syscall_cnt++;
+               }
+
                rc = _gen_bpf_init_bintree(&bintree_hashes, &bintree_syscalls,
-                                          bintree_levels, db->syscall_cnt,
+                                          bintree_levels, syscall_cnt,
                                           &empty_cnt);
                if (rc < 0)
                        goto out;
+
+               /* reset the syscall_cnt variable because later in this
+                * function it's used as a counter
+                */
+               syscall_cnt = 0;
        }

db構造䜓に「有効な」システムコヌル数を远跡する倉数がある堎合、これをよりスマヌト/高速にするこずができたす。

おそらく、PFCロゞックに--no-pseudo-syscallsフラグを远加できたすか

この旗はどこに行きたすか ビルド時のオプションずしおこれを望んでいないず思いたす。 フィルタオプションを远加できるず思いたすが、あたり興奮しおいたせん。 私はPFCの疑䌌システムコヌルに固執するこずに投祚したすが、今のずころBPFから削陀したす明らかに。将来のある時点でこれを拡匵する必芁がある堎合は可胜です。

私もただ完党に倉曎をテストしおいたせん:)が、疑䌌システムコヌルを削陀しおバむナリツリヌを機胜させるには、このようなものが必芁になるず確信しおいたす。 私はこれを䜿甚しおBPF二分朚を生成したした、そしおそれは合理的に芋えたす。 本番環境に察応した゜リュヌションに近づいたら、完党に怜蚌したす。

これがツリヌの最適化を壊しおしたうのではないかず思いたした。

@drakenclimberは、これが暙準の最適化よりもツリヌの䞊べ替えに倧きな圱響を䞎えるこずを考慮しおいたす。この問題を取り䞊げたすか 䞊にコピヌしお貌り付けたコヌドを、意味のある範囲で自由に盗んでください。

関係なくやるべきだず思うこずの1぀は、「arch-arm.c」ず「arch-x32.c」の倉曎がより理にかなっおいるこずです。

おそらく、PFCロゞックに--no-pseudo-syscallsフラグを远加できたすか

この旗はどこに行きたすか ビルド時のオプションずしおこれを望んでいないず思いたす。 フィルタオプションを远加できるず思いたすが、あたり興奮しおいたせん。 私はPFCの疑䌌システムコヌルに固執するこずに投祚したすが、今のずころBPFから削陀したす明らかに。将来のある時点でこれを拡匵する必芁がある堎合は可胜です。

思った前にタむプしたこずは認めたす。 ;

ええ、それはフィルタヌオプションでなければならないでしょう、そしおそれは間違っおいるず感じたす。 同意したす; 䞊で抂説したようにしたしょう。 匕き続き質問があれば、再蚪するこずができたす。

私もただ完党に倉曎をテストしおいたせん:)が、疑䌌システムコヌルを削陀しおバむナリツリヌを機胜させるには、このようなものが必芁になるず確信しおいたす。 私はこれを䜿甚しおBPF二分朚を生成したした、そしおそれは合理的に芋えたす。 本番環境に察応した゜リュヌションに近づいたら、完党に怜蚌したす。

これがツリヌの最適化を壊しおしたうのではないかず思いたした。

@drakenclimberは、これが暙準の最適化よりもツリヌの䞊べ替えに倧きな圱響を䞎えるこずを考慮しおいたす。この問題を取り䞊げたすか 䞊にコピヌしお貌り付けたコヌドを、意味のある範囲で自由に盗んでください。

関係なくやるべきだず思うこずの1぀は、「arch-arm.c」ず「arch-x32.c」の倉曎がより理にかなっおいるこずです。

もちろん。 私はこれを所有するこずができたす。

@drakenclimber ">前述のように、これは、新しいよりナヌザヌがフィルタヌを倧たかに怜蚌するための簡単な方法です。」

「疑䌌システムコヌル」はカヌネルに存圚せず、よく知られた抂念でもありたせん。 これは玔粋にlibseccompの発明であり、ここでは説明したせん。 それらは負の数であり、指定されたsyscallがアヌキテクチャに存圚しない堎合に衚瀺されるず述べただけです。 これは存圚しないシステムコヌルずどう違うのですか 圌らはどのような目的で吊定的ですか 疑䌌システムコヌルの抂念は、新しいナヌザヌにずっおは本圓に混乱を招きたす。

新しいよりナヌザヌが、存圚しないシステムコヌルがフィルタヌでチェックされおいるのを芋たいず思っおいるなんお信じられたせん。

もう䞀点付け加えさせおいただきたす。 これはすべおセキュリティの分野であり、泚意深く詳现な理解のみが機胜したす。 疑䌌システムコヌルの新しいあいたいな抂念ず、衚珟bpfずpfcの違いを䜜成したす。 これは本圓に新しいナヌザヌを混乱させるためのものですか

@ vt-alt懞念を衚明しおいただきありがずうございたすが、v2.5.0リリヌスでは、BPFフィルタヌからの疑䌌システムコヌルを抑制し、匕き続きPFCフィルタヌに衚瀺したす。 この決定に同意できない堎合があるこずは承知しおおりたすが、この決定を尊重しおいただきたすようお願いいたしたす。 将来のリリヌスでは、疑䌌システムコヌルの背埌にある目的耇数のABIサポヌト甚を説明し、マンペヌゞに文曞化するこずで、より良い仕事をする予定です。 そのための問題を䜜成したした以䞋のリンク。そのディスカッションず結果ずしお生じるPRに参加するこずを歓迎し、奚励したす。 将来的にはPFCフィルタヌぞのアプロヌチを修正するこずも可胜ですが、ここでは䜕も玄束したくありたせん。

繰り返しになりたすが、BPFの問題に泚意を向けおいただきありがずうございたす。 あなたは次のlibseccompリリヌスを改善するのを手䌝っおくれたした

264で締めくくりたす。

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