Libseccomp: س: لا يمكن أن يكون لديك عوامل تصفية مختلفة مع SCMP_ACT_NOTIFY في مواضيع مختلفة

تم إنشاؤها على ٦ نوفمبر ٢٠٢٠  ·  9تعليقات  ·  مصدر: seccomp/libseccomp

يخزن libseccomp الإخطار fd في متغير عام: state.notify_fd . هذا يجعل من المستحيل استخدام libseccomp لتطبيق متعدد الخيوط مع مرشحات مختلفة في خيوط مختلفة (أي بدون استخدام TSYNC).

يحتوي libseccomp على seccomp_reset(NULL, ...) لإعادة تعيين المتغير العام state.notify_fd . لكن seccomp_reset() له نتيجة مؤسفة لإعادة تعيين state.nr_seccomp = -1 .

تمت ملاحظة هذه المشكلة عند محاولة حل اختبارات الوحدة في libseccomp-golang ، راجع https://github.com/seccomp/libseccomp-golang/pull/59#issuecomment -723045033

سم مكعبyvesfrata

prioritlow question

التعليق الأكثر فائدة

يبدو أننا جميعًا متفقون هنا ، لذا سأغلق هذه المسألة. alban إذا كنت تعتقد أننا حلها بالكامل .

شكرا لكم جميعا.

ال 9 كومينتر

drakenclimber عقد seccomp_reset(NULL, ...) ، فلننتظر دقيقة واحدة فقط حتى نتمكن من التحقق من الأشياء ...

إضافة هذا إلى الإصدار v2.5.1 الأساسي كمجرد مانع في الوقت الحالي ، قد يتغير هذا عندما نتحرى الأمور.

drakenclimber عقد seccomp_reset(NULL, ...) ، فلننتظر دقيقة واحدة فقط حتى نتمكن من التحقق من الأشياء ...

متفق. سوف تفعل.

يخزن libseccomp الإخطار fd في متغير عام: state.notify_fd . هذا يجعل من المستحيل استخدام libseccomp لتطبيق متعدد الخيوط مع مرشحات مختلفة في خيوط مختلفة (أي بدون استخدام TSYNC).

هل يمكنك التوسع قليلاً في الجملة الأخيرة؟ لست متأكدًا من أنني أفهم ما تحاول نقله.

FWIW ، إخطار seccomp FD هو كائن عمومي للعملية ، يمكنك فقط طلبه من kernel مرة واحدة. يمكنك قراءة https://github.com/seccomp/libseccomp/issues/273 للحصول على مزيد من المعلومات الأساسية حول المشكلة.

يحتوي libseccomp على seccomp_reset(NULL, ...) لإعادة تعيين المتغير العام state.notify_fd . لكن seccomp_reset() له نتيجة مؤسفة لإعادة تعيين state.nr_seccomp = -1 .

لماذا تعد إعادة تعيين state.nr_seccomp = -1 مشكلة كبيرة؟ إذا تمت إعادة تعيين الحقل nr_seccomp إلى -1 في المرة التالية التي تُطلب فيها عملية يمكن أن تستخدم seccomp(2) ، تتحقق المكتبة من دعم seccomp(2) ويستخدمها إذا كانت متوفرة. نعم ، يمكن أن يؤدي ذلك إلى مكالمات إضافية إلى seccomp(2) ولكن لا ينبغي أن تكون هذه مشكلة كبيرة ، هل هذا مصدر قلق لحالة الاستخدام الخاصة بك؟

alban - سؤال مشابه مني. لقد أمضيت بعض الوقت في محاولة ابتكار حالة استخدام معقولة متعددة الخيوط ومتعددة ثوانٍ للفلتر (في C) ولم أتمكن حقًا من التوصل إلى أي شيء.

قرأت من خلال وثائق Go من os.LockOSThread() ، وهذا أمر منطقي بالنسبة لي. لكني أجد صعوبة في تحويل هذه المعرفة إلى حل متعدد الخيوط ، متعدد الترشيح.

هل يمكنك مشاركة بعض الرموز الزائفة أو بعض التصميمات عالية المستوى لما تفكر فيه؟ سأكون مسرورًا بنمذجه الأولي في C بعد ذلك.

هل يمكنك التوسع قليلاً في الجملة الأخيرة؟ لست متأكدًا من أنني أفهم ما تحاول نقله.

أثناء العمل على اختبارات الوحدة في libseccomp-golang ، أدركت أن السيناريو التالي قيد الاختبار:

  1. في أول تنفيذ لاختبار الوحدة ، تم تطبيق نهج seccomp بدون SECCOMP_FILTER_FLAG_TSYNC (بمعنى أنه يتم تطبيقه على مستوى مؤشر الترابط وليس على مستوى العملية) ولكن مع SECCOMP_FILTER_FLAG_NEW_LISTENER (لذلك سيتم تخزين libseccomp fd في state.notify_fd ).
  2. يتم تنفيذ نفس اختبار الوحدة مرة أخرى في نفس العملية ولكن في سلسلة مختلفة (باستخدام runtime.LockOSThread في Go للتأكد من ذلك). لكن libseccomp يعيد استخدام fd من عامل تصفية seccomp السابق (من state.notify_fd ) بدلاً من الحصول على fd جديد لعامل التصفية الجديد. ثم يفشل الاختبار لأننا نتوقع تلقي الأحداث على seccomp fd الخاطئ.

FWIW ، إخطار seccomp FD هو كائن عمومي للعملية ، يمكنك فقط طلبه من kernel مرة واحدة. يمكنك قراءة # 273 للحصول على مزيد من المعلومات الأساسية حول هذه القضية.

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

لم يتم إنشاء هذا السيناريو لاستخدام أشجار الفلاتر المختلفة مع SECCOMP_FILTER_FLAG_NEW_LISTENER عن قصد ، لقد ظهر للتو كنتيجة لاختبارات وحدة libseccomp-golang التي تعمل في نفس العملية. ولكن نظرًا لأن السبب الأساسي هو libseccomp باستخدام متغير عالمي state.notify_fd يتم مشاركته بين سلاسل الرسائل ، أعتقد أنه يجب علي فتح هذا الخطأ هنا لفتح المناقشة. ومع ذلك ، سأكون بخير إذا تم إغلاق هذا باسم "WONTFIX" (لا أعرف ما إذا كان المستخدمون الآخرون في libseccomp سيحتاجون إلى دعم لهذا النوع من السيناريو). في هذه الحالة ، يمكننا فقط كتابة اختبارات وحدة libseccomp-golang بطريقة مختلفة (أي باستخدام عملية منفصلة لكل تكرار اختبار) ؛ سيتعين علينا القيام بذلك على أي حال (لتجنب خلط مرشحات مستوى الخيط ومرشحات مستوى العملية - التي قد ترفضها النواة).

أثناء العمل على اختبارات الوحدة في libseccomp-golang ، أدركت أن السيناريو التالي قيد الاختبار:

  1. في أول تنفيذ لاختبار الوحدة ، تم تطبيق نهج seccomp بدون SECCOMP_FILTER_FLAG_TSYNC (بمعنى أنه يتم تطبيقه على مستوى مؤشر الترابط وليس على مستوى العملية) ولكن مع SECCOMP_FILTER_FLAG_NEW_LISTENER (لذلك سيتم تخزين libseccomp fd في state.notify_fd ).
  2. يتم تنفيذ نفس اختبار الوحدة مرة أخرى في نفس العملية ولكن في سلسلة مختلفة (باستخدام runtime.LockOSThread في Go للتأكد من ذلك). لكن libseccomp يعيد استخدام fd من عامل تصفية seccomp السابق (من state.notify_fd ) بدلاً من الحصول على fd جديد لعامل التصفية الجديد. ثم يفشل الاختبار لأننا نتوقع تلقي الأحداث على seccomp fd الخاطئ.

آه ها ، هذا منطقي أكثر الآن. غالبًا ما تساءلت عما إذا كان يجب أن نجعل TSYNC الخيار الافتراضي لربط libseccomp-golang ؛ نظرًا لغموض الخيط في Go ، يبدو أنه خيار أكثر أمانًا.

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

لم يتم إنشاء هذا السيناريو لاستخدام أشجار الفلاتر المختلفة مع SECCOMP_FILTER_FLAG_NEW_LISTENER عن قصد ، لقد ظهر للتو كنتيجة لاختبارات وحدة libseccomp-golang التي تعمل في نفس العملية. ولكن نظرًا لأن السبب الأساسي هو libseccomp باستخدام متغير عالمي state.notify_fd يتم مشاركته بين سلاسل الرسائل ، أعتقد أنه يجب علي فتح هذا الخطأ هنا لفتح المناقشة. ومع ذلك ، سأكون بخير إذا تم إغلاق هذا باسم "WONTFIX" (لا أعرف ما إذا كان المستخدمون الآخرون في libseccomp سيحتاجون إلى دعم لهذا النوع من السيناريو). في هذه الحالة ، يمكننا فقط كتابة اختبارات وحدة libseccomp-golang بطريقة مختلفة (أي باستخدام عملية منفصلة لكل تكرار اختبار) ؛ سيتعين علينا القيام بذلك على أي حال (لتجنب خلط مرشحات مستوى الخيط ومرشحات مستوى العملية - التي قد ترفضها النواة).

سأكون مهتمًا بالحصول على رأي drakenclimber حول هذا ، ولكن نعم ، ما أفكر به الآن هو أن هذه "WONTFIX" نظرًا لكونها قضية زاوية غريبة إلى حد ما. إذا أراد أحد التطبيقات القيام بشيء من هذا القبيل ، فيمكنه حفظ الإخطار fd من شجرة المرشح "A" ، وإعادة تعيين libseccomp ، ثم استرداد fd وحفظه من شجرة التصفية "B".

من أجل "إصلاح" هذا في libseccomp ، سنحتاج إلى جعل موضوع libseccomp مدركًا ، والذي يأتي مع عدد من التحديات والمزالق ، لذا فأنا حاليًا أعتقد أن هذه ستكون فكرة سيئة. ومع ذلك ، من أجل الوسيطة ، إذا جعلنا مؤشر ترابط libseccomp مدركًا ، فيمكننا أيضًا جعل الحالة العامة الداخلية حالة معينة لمؤشر الترابط و / أو ربما حالة معينة لشجرة عامل التصفية ؛ في أي من هاتين الحالتين ، أعتقد أن واجهة برمجة التطبيقات الحالية (بما في ذلك seccomp_reset(NULL, ...) ) ستظل معقولة ، لذا فأنا أميل إلى ترك الأشياء كما هي مع واجهة برمجة التطبيقات. إذا كان لدى أي شخص أي مخاوف بشأن ذلك ، فيرجى إخبارنا بذلك قريبًا.

تضمين التغريدة باستثناء أي اعتراضات على ما ورد أعلاه ، أعتقد أننا عدنا لإصدار v2.5.1.

سأكون مهتمًا بالحصول على رأي drakenclimber حول هذا ، ولكن نعم ، ما أفكر به الآن هو أن هذه "WONTFIX" نظرًا لكونها قضية زاوية غريبة إلى حد ما. إذا أراد أحد التطبيقات القيام بشيء من هذا القبيل ، فيمكنه حفظ الإخطار fd من شجرة المرشح "A" ، وإعادة تعيين libseccomp ، ثم استرداد fd وحفظه من شجرة التصفية "B".

أنا موافق. قضيت بعض الوقت في البحث في مجموعة التصحيح والتعليقات الأصلية لـ

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

جانبًا واحدًا - لقد تمكنت من الحصول على kernel لإرجاع fds للإخطارات المتعددة إلى عملية ما. من خلال إنشاء العديد من pthreads وجعلهم جميعًا يقومون على الفور بتحميل عامل تصفية seccomp مع إجراء إشعار ، تمكنت أحيانًا من الحصول على اثنين أو ثلاثة ملفات إعلام مختلفة تم إرجاعها إلى عملية مساحة المستخدم. نظرًا لأن هذا غير واقعي للغاية ، فإنني أميل إلى تمييز مشكلة kernel هذه على أنها WONTFIX أيضًا.

تضمين التغريدة باستثناء أي اعتراضات على ما ورد أعلاه ، أعتقد أننا عدنا لإصدار v2.5.1.

رائعة. يجب أن أكون قادرًا على بدء العمل عليه في أوائل الأسبوع المقبل.

يبدو أننا جميعًا متفقون هنا ، لذا سأغلق هذه المسألة. alban إذا كنت تعتقد أننا حلها بالكامل .

شكرا لكم جميعا.

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