تنفيذ 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 ، لذا لا يمكنني إيجاد حل بديل.
مرحبا @ 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 الفعلي
لكن الوظائف الجديدة
تستخدم _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 ،
التعليق الأكثر فائدة
آه ... آسف لذلك. في الواقع ، يتعمق الأمر بشكل أعمق من مستوى واجهة برمجة التطبيقات ، انظر في "system.c" وستلاحظ أن استدعاءات مستوى نظام libseccomp لا تنشر هذه الوظائف على مستوى واجهة برمجة التطبيقات. بالنظر إلى manpages ، يبدو أننا لا نقدم أي مطالبات حول
SCMP_FLTATR_API_SYSRAWRC
لواجهة برمجة تطبيقات الإخطار (انظرseccomp_load(3)
للحصول على مثال العداد).سأمضي قدمًا وأعيد فتح هذا باعتباره RFE نظرًا لأننا لا نقدم حاليًا أي مطالبات حول هذا العمل.
drakenclimber أعتقد أن هذه مادة v2.6.x (ربما v2.5.2) لأنني لا أريد إبطاء إصدار v2.5.1. إذا كنت تعتقد خلاف ذلك، اسمحوا لي أن أعرف.