Libseccomp: RFE: تمديد دعم SCMP_FLTATR_API_SYSRAWRC لواجهة برمجة تطبيقات الإعلام

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

تنفيذ seccomp_notify_receive() يستخدم فقط:

        if (ioctl(fd, SECCOMP_IOCTL_NOTIF_RECV, req) < 0)
                return -ECANCELED;

بغض النظر عن الخطأ الموجود في errno ، فإنه يُرجع -ECANCELED .

عند تصحيح الأخطاء باستخدام strace ، اكتشفت أن ioctl أعاد EINTR بسبب إشارة SIGURG:

1448850 ioctl(7, SECCOMP_IOCTL_NOTIF_RECV <unfinished ...>
1448230 getpid()                        = 1448217
1448230 tgkill(1448217, 1448850, SIGURG) = 0
1448850 <... ioctl resumed>, 0x7fc65d49ecd0) = -1 EINTR (Interrupted system call)

يتم إنشاء إشارة SIGURL بواسطة وقت تشغيل Golang ، راجع التفاصيل في https://go-review.googlesource.com/c/go/+/232862/
وفقًا لهذا التقرير ، يجب إعادة إصدار مكالمة النظام فقط عند الحصول على EINTR.
من الناحية المثالية ، يجب أن يعتني موقع libseccomp بهذا الأمر ، لذا فهو شفاف للمستخدمين.

كحل بديل ، حاولت إعادة إصدار syscall عن طريق استدعاء seccomp_notify_receive () في برنامجي ، والقيام بنفس الشيء في seccomp_notify_respond() لأنه يحتوي على نفس النمط:

        if (ioctl(fd, SECCOMP_IOCTL_NOTIF_SEND, resp) < 0)
                return -ECANCELED;

لكن في بعض الأحيان أحصل على قيمة الإرجاع errno = ENOENT:

1497880 ioctl(12, SECCOMP_IOCTL_NOTIF_SEND, 0x7f718fd28e10) = -1 ENOENT (No such file or directory)

لا يسمح لي libseccomp بالتمييز بين ENOENT (تمت مقاطعة العملية المستهدفة قبل استدعاء SECCOMP_IOCTL_NOTIF_SEND ) و EINTR (تمت مقاطعة وكيل seccomp بواسطة إشارة SIGURG).

بالإضافة إلى ذلك ، لا يمكنني قراءة errno من Golang ، لذا لا يمكنني إيجاد حل بديل.

enhancement prioritmedium

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

لكن الدوال الجديدة ... تستخدم _rc_filter () وليس _rc_filter_sys () ...

آه ... آسف لذلك. في الواقع ، يتعمق الأمر بشكل أعمق من مستوى واجهة برمجة التطبيقات ، انظر في "system.c" وستلاحظ أن استدعاءات مستوى نظام libseccomp لا تنشر هذه الوظائف على مستوى واجهة برمجة التطبيقات. بالنظر إلى manpages ، يبدو أننا لا نقدم أي مطالبات حول SCMP_FLTATR_API_SYSRAWRC لواجهة برمجة تطبيقات الإخطار (انظر seccomp_load(3) للحصول على مثال العداد).

سأمضي قدمًا وأعيد فتح هذا باعتباره RFE نظرًا لأننا لا نقدم حاليًا أي مطالبات حول هذا العمل.

drakenclimber أعتقد أن هذه مادة v2.6.x (ربما v2.5.2) لأنني لا أريد إبطاء إصدار v2.5.1. إذا كنت تعتقد خلاف ذلك، اسمحوا لي أن أعرف.

ال 5 كومينتر

مرحبا @ alban.

انظر إلى SCMP_FLTATR_API_SYSRAWRC في صفحة الإدارة seccomp_attr_set(3) :

علامة لتحديد ما إذا كان يجب على libseccomp إعادة رموز خطأ النظام إلى المتصل بدلاً من الافتراضي -ECANCELED. افتراضيات إيقاف (القيمة == 0).

نفرض -ECANCELED في هذه الحالة لضمان وعد كود إرجاع ثابت في libseccomp API عبر إصدارات kernel / libc المختلفة. نحن نقدم SCMP_FLTATR_API_SYSRAWRC للمتصلين الذين ما زالوا يرغبون في رؤية كود إرجاع kernel / libc الفعلي ، فقط كن حذرًا من أننا لا نضمن رمز إرجاع ثابتًا إذا قمت بتمكين هذه السمة.

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

مرحبًا pcmoore ، شكرًا على الرد السريع.

نقدم SCMP_FLTATR_API_SYSRAWRC للمتصلين الذين ما زالوا يرغبون في رؤية كود إرجاع kernel / libc الفعلي

لكن الوظائف الجديدة

  • seccomp_notify_receive
  • seccomp_notify_r response
  • seccomp_notify_id_valid

تستخدم _rc_filter() وليس _rc_filter_sys() ، لذلك لا يجب أن يكون لـ SCMP_FLTATR_API_SYSRAWRC تأثير ، إذا لم أكن مخطئًا.

لكن الدوال الجديدة ... تستخدم _rc_filter () وليس _rc_filter_sys () ...

آه ... آسف لذلك. في الواقع ، يتعمق الأمر بشكل أعمق من مستوى واجهة برمجة التطبيقات ، انظر في "system.c" وستلاحظ أن استدعاءات مستوى نظام libseccomp لا تنشر هذه الوظائف على مستوى واجهة برمجة التطبيقات. بالنظر إلى manpages ، يبدو أننا لا نقدم أي مطالبات حول SCMP_FLTATR_API_SYSRAWRC لواجهة برمجة تطبيقات الإخطار (انظر seccomp_load(3) للحصول على مثال العداد).

سأمضي قدمًا وأعيد فتح هذا باعتباره RFE نظرًا لأننا لا نقدم حاليًا أي مطالبات حول هذا العمل.

drakenclimber أعتقد أن هذه مادة v2.6.x (ربما v2.5.2) لأنني لا أريد إبطاء إصدار v2.5.1. إذا كنت تعتقد خلاف ذلك، اسمحوا لي أن أعرف.

شكرا!

للتسجيل ، وجدت الحل البديل في جانب Golang لأتمكن من التمييز بين ENOENT و EINTR ، باستخدام نمط الكود هذا:

-   if retCode := C.seccomp_notify_respond(C.int(fd), resp); retCode != 0 {
-       return errRc(retCode)
+   for {
+       retCode, errno := C.seccomp_notify_respond(C.int(fd), resp)
+       if errno == syscall.EINTR {
+           continue
+       }
+       if errno == syscall.ENOENT {
+           return errno
+       }
+       if retCode != 0 {
+           return errRc(retCode)
+       }
+       break
    }

مع هذا ، يبدو أنه يعمل بشكل جيد مع libseccomp-2.5.0 ،

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