Libseccomp: BUG: لا تنشئ BPF لمكالمات syscalls الزائفة

تم إنشاؤها على ١٥ يونيو ٢٠٢٠  ·  20تعليقات  ·  مصدر: seccomp/libseccomp

راجع العدد رقم 249 ، وتحديدًا هذا التعليق :

لماذا التحقق من syscall 4294957285 غير موجود في bpf الذي تم إنشاؤه بالفعل؟

لا ينبغي لنا ذلك ، ولم نعتد على القيام بذلك ، ولكن يبدو أن libseccomp الحالي به خلل هنا.

الائتمان إلى @ vt-alt للإبلاغ عن هذا الخطأ.

bug prioritmedium

ال 20 كومينتر

تمت إزالة أداة إعادة الإنتاج لصالح المسودة المحسّنة أدناه

لكي نكون واضحين ، لا يزال يتعين علينا أن نطلق عمليات syscalls الزائفة في PFC ، لأغراض تصحيح الأخطاء ، لكن لا ينبغي لنا إصدار قاعدة مرشح BPF (عديمة الفائدة).

شكرا لخلق المشكلة من تقريري.

لكي نكون واضحين ، لا يزال يتعين علينا أن نطلق عمليات syscalls الزائفة في PFC ، لأغراض تصحيح الأخطاء ، لكن لا ينبغي لنا إصدار قاعدة مرشح BPF (عديمة الفائدة).

يرجى إعادة التفكير في هذا. أعتقد أن هذا لن يؤدي إلا إلى تعقيد وإخفاء الأشياء إذا لم تعكس PFC BPF.

يرجى إعادة التفكير في هذا. أعتقد أن هذا لن يؤدي إلا إلى تعقيد وإخفاء الأشياء إذا لم تعكس PFC BPF.

إذا كان syscall مفقودًا من PFC ، فسنستلم عددًا من تقارير الأخطاء الزائفة التي تتحدث عن فشل المكتبة في إضافة عامل تصفية لمكالمات النظام (غير الموجودة).

بالنسبة لأولئك الذين يفهمون مفهوم الكشوف الزائفة ، فإن إزالتها من إخراج PFC يعد تمرينًا تافهًا. من الجدير بالذكر أيضًا أن إخراج PFC لا يُقصد به أن يكون نسخة طبق الأصل من إخراج BPF ، فهو موجود ببساطة كأداة لتصحيح الأخطاء وطريقة سهلة لتصور كود المرشح الذي تم إنشاؤه.

طريقة سهلة لتصور رمز المرشح الذي تم إنشاؤه

ولكن ، بعد ذلك ، لن يتخيل رمز عامل التصفية _ المُنشأ_ لأنه في الكود الذي تم إنشاؤه ، يجب أن تكون عمليات syscall syscalls غير موجودة.

إذا كان syscall مفقودًا من PFC ، فسنستلم عددًا من تقارير الأخطاء الزائفة التي تتحدث عن فشل المكتبة في إضافة عامل تصفية لمكالمات النظام (غير الموجودة).

من الأسهل كثيرًا أن نفهم أن فحوصات syscall الزائفة لا ينبغي أن تكون موجودة في الكود (كما هو الحال في "الخروج المحسن" ، لأنه "لا توجد مثل هذه النداءات للقوس") ، من الاختلاف المنطقي (وجود وغياب الشروط الشرطية) في تصور الكود والكود الفعلي.

أفضل أن تعكس PFC bpf بدلاً من استخدام scmp_bpf_disasm لأن إخراج PFC أسهل في القراءة.

أتفهم قلقك على @ vt-alt ، وربما في إصدار مستقبلي نقوم بذلك باستخدام PFC ، لكن في رأيي أن إزالة syscalls الزائفة من إخراج 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 ، لكن في رأيي أن إزالة syscalls الزائفة من إخراج PFC يعد خطأ.

drakenclimber هل لديك أي آراء قوية حول هذا؟

ليس حقًا ، لكنني أعتقد أن جذر المشكلة هو أن إخراج PFC يتم استخدامه بطرق متعددة ومتباينة:

  1. كما ذكرنا سابقًا ، إنها طريقة سهلة للمستخدمين الجدد للتحقق تقريبًا من عامل التصفية الخاص بهم
  2. يتوقع المستخدمون الأكثر تقدمًا أن يكون تقريبًا تقريبيًا لمرشح BPF الفعلي

ربما يمكننا إضافة علامة --no-pseudo-syscalls إلى منطق PFC؟ بعد ذلك يمكن أن يظل هو نفسه للمستخدمين المبتدئين ، ولكن يمكن للمستخدمين المتقدمين الحصول على تقريب أفضل لـ BPF.

_ محدث: تم إصلاح مشكلة TSKIP_

لم يتم اختباره بالكامل بعد ، ولكن قد يكون هذا إصلاحًا - هل يمكنك التحقق من أن هذا معقول بالنسبة لخوارزمية تحسين الشجرة المتوازنةdrakenclimber؟

سوف تفعل. أريد معرفة ما إذا كان بإمكاني إجراء اختبار آلي من شأنه إعادة إنتاج هذا السيناريو.

_ محدث: تم إصلاح مشكلة TSKIP_
لم يتم اختباره بالكامل بعد ، ولكن قد يكون هذا إصلاحًا - هل يمكنك التحقق من أن هذا معقول بالنسبة لخوارزمية تحسين الشجرة المتوازنةdrakenclimber؟

سوف تفعل. أريد معرفة ما إذا كان بإمكاني إجراء اختبار آلي من شأنه إعادة إنتاج هذا السيناريو.

وبالطبع سأبدأ باختبار التكاثر الذي أجريته أعلاه. شكرا!

_ محدث: تم إصلاح مشكلة 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 لتتبع عدد مكالمات النظام "الصالح".

ربما يمكننا إضافة علم - no-pseudo-syscalls إلى منطق PFC؟

إلى أين يذهب هذا العلم؟ لا أعتقد أننا نريد هذا كخيار وقت البناء. أفترض أنه يمكننا إضافة خيار تصفية ، لكنني لست متحمسًا حقًا بشأن ذلك. كنت سأصوت للالتزام بالنكات الزائفة في PFC ولكن أسقطها من BPF (من الواضح) في الوقت الحالي ، وإذا احتجنا إلى زيادة هذا في وقت ما في المستقبل يمكننا ذلك.

لم أختبر تغييراتي بالكامل بعد أيضًا :) ، لكنني متأكد تمامًا من أننا سنحتاج إلى شيء مثل هذا لجعل الشجرة الثنائية تعمل مع إزالة الكسور الزائفة. لقد أنشأت شجرة ثنائية BPF باستخدام هذا ويبدو معقولًا. مع اقترابنا من حل جاهز للإنتاج ، سأتحقق منه تمامًا.

كنت أظن أن هذا سيؤدي إلى كسر تحسين الشجرة.

drakenclimber بالنظر إلى أن هذا يؤثر على فرز الشجرة أكثر بكثير من التحسين القياسي ، هل تريد معالجة هذه المشكلة؟ لا تتردد في سرقة الكثير أو القليل من الكود الذي أنسخه والصقه أعلاه كما هو منطقي.

شيء واحد أعتقد أننا يجب أن نفعله بغض النظر عن التغييرات في "arch-arm.c" و "arch-x32.c" لأنه أكثر منطقية.

ربما يمكننا إضافة علم - no-pseudo-syscalls إلى منطق PFC؟

إلى أين يذهب هذا العلم؟ لا أعتقد أننا نريد هذا كخيار وقت البناء. أفترض أنه يمكننا إضافة خيار تصفية ، لكنني لست متحمسًا حقًا بشأن ذلك. كنت سأصوت للالتزام بالنكات الزائفة في PFC ولكن أسقطها من BPF (من الواضح) في الوقت الحالي ، وإذا احتجنا إلى زيادة هذا في وقت ما في المستقبل يمكننا ذلك.

أعترف أنني كتبت قبل أن أفكر. ؛)

نعم ، يجب أن يكون خيار تصفية وهذا شعور خاطئ. أنا موافق؛ لنفعل ما أوضحته أعلاه. إذا واصلنا تلقي الأسئلة ، فيمكننا إعادة النظر.

لم أختبر تغييراتي بالكامل بعد أيضًا :) ، لكنني متأكد تمامًا من أننا سنحتاج إلى شيء مثل هذا لجعل الشجرة الثنائية تعمل مع إزالة الكسور الزائفة. لقد أنشأت شجرة ثنائية BPF باستخدام هذا ويبدو معقولًا. مع اقترابنا من حل جاهز للإنتاج ، سأتحقق منه تمامًا.

كنت أظن أن هذا سيؤدي إلى كسر تحسين الشجرة.

drakenclimber بالنظر إلى أن هذا يؤثر على فرز الشجرة أكثر بكثير من التحسين القياسي ، هل تريد معالجة هذه المشكلة؟ لا تتردد في سرقة الكثير أو القليل من الكود الذي أنسخه والصقه أعلاه كما هو منطقي.

شيء واحد أعتقد أننا يجب أن نفعله بغض النظر عن التغييرات في "arch-arm.c" و "arch-x32.c" لأنه أكثر منطقية.

بالتأكيد. يمكنني امتلاك هذا.

drakenclimber "> كما هو مذكور أعلاه ، إنها طريقة سهلة للمستخدمين الجدد (er) للتحقق تقريبًا من عامل التصفية"

لا يوجد "pseudo syscall" في النواة وهو ليس مفهومًا معروفًا أيضًا. إنه مجرد اختراع libseccomp ولا يتم شرحه هنا. تم ذكرها فقط أنها أرقام سالبة وتظهر عند عدم وجود مكالمة syscall معينة للهندسة المعمارية. كيف يختلف هذا عن syscall غير موجود؟ لأي غرض هي سلبية؟ إن مفهوم syscall الزائف محير حقًا للمستخدمين الجدد.

لا أستطيع أن أصدق أن المستخدمين الجدد (إيه) يريدون رؤية عمليات تسجيل غير موجودة محددة في عوامل التصفية الخاصة بهم.

اسمحوا لي أن أضيف نقطة واحدة أخرى. كل هذا في مجال الأمن ، حيث يعمل الفهم الدقيق والمفصل فقط. أنت تقوم بإنشاء مفاهيم جديدة غامضة (من syscalls الزائفة) والفرق بين التمثيلات (bpf و pfc). هل هذا حقًا مخصص للمستخدمين الجدد لإرباكهم أكثر؟

@ vt-alt شكرًا لك على التعبير عن قلقك ، ولكن بالنسبة لإصدار v2.5.0 ، سنقوم بإيقاف عمليات syscalls الزائفة من مرشح BPF ، وسنواصل عرضها في مرشح PFC. أدرك أنك قد لا توافق على هذا القرار ولكني أطلب منك التفضل باحترام هذا القرار. في الإصدارات المستقبلية ، سنقوم بعمل أفضل في شرح الغرض من وراء عمليات السحاب الزائفة (لدعم ABI المتعدد) وتوثيقه في Manpages ؛ لقد قمت بإنشاء مشكلة لذلك (الرابط أدناه) ، فنحن نرحب بك ونشجعك على المشاركة في تلك المناقشة وأي علاقات عامة تنتج عنها. من الممكن أيضًا أن نراجع نهجنا في مرشح PFC في المستقبل ، لكنني لا أريد أن أعد بشيء هنا.

مرة أخرى ، نشكرك على لفت انتباهنا إلى مشكلة BPF ؛ لقد ساعدت في تحسين إصدار libseccomp التالي!

الإغلاق عبر # 264.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات