مشروع لنقل آلية عزل التعهد إلى Linux

أعلن مؤلف مكتبة C القياسية العالمية ومنصة Redbean عن تنفيذ آلية عزل التعهد () لنظام التشغيل Linux. تم تطوير Pledge في الأصل بواسطة مشروع OpenBSD ويسمح لك بمنع التطبيقات بشكل انتقائي من الوصول إلى مكالمات النظام غير المستخدمة (يتم تشكيل نوع من القائمة البيضاء لاستدعاءات النظام للتطبيق، ويتم حظر المكالمات الأخرى). على عكس آليات تقييد مكالمات النظام المتوفرة في Linux، مثل seccomp، فقد تم تصميم آلية التعهد في الأصل لتكون بسيطة قدر الإمكان.

أظهرت المبادرة الفاشلة لعزل التطبيقات في بيئة OpenBSD الأساسية باستخدام آلية systrace أن العزل على مستوى استدعاءات النظام الفردية كان معقدًا للغاية ويستغرق وقتًا طويلاً. كبديل، تم اقتراح تعهد، مما يجعل من الممكن إنشاء قواعد العزل دون الخوض في التفاصيل والتلاعب بفئات الوصول الجاهزة. على سبيل المثال، الفئات المقدمة هي stdio (الإدخال/الإخراج)، rpath (ملفات للقراءة فقط)، wpath (كتابة الملفات)، cpath (إنشاء الملفات)، tmppath (العمل مع الملفات المؤقتة)، inet (مآخذ الشبكة)، unix ( Unix، وDNS (تحليل DNS)، وgetpw (الوصول للقراءة إلى قاعدة بيانات المستخدم)، وioctl (استدعاء ioctl)، وproc (إدارة العمليات)، وexec (تشغيل العملية)، وid (إدارة حقوق الوصول).

يتم تحديد قواعد العمل مع مكالمات النظام في شكل تعليقات توضيحية، بما في ذلك قائمة الفئات المسموح بها لاستدعاءات النظام ومجموعة من مسارات الملفات التي يُسمح بالوصول إليها. بعد إنشاء التطبيق المعدل وتشغيله، تتولى النواة مهمة مراقبة الامتثال للقواعد المحددة.

يتم تطوير تنفيذ منفصل للتعهد لـ FreeBSD، والذي يتميز بالقدرة على عزل التطبيقات دون إجراء تغييرات على الكود الخاص بها، بينما في OpenBSD يهدف استدعاء التعهد إلى التكامل المحكم مع البيئة الأساسية وإضافة التعليقات التوضيحية إلى الكود الخاص بكل منها. طلب.

أخذ مطورو منفذ التعهد لنظام التشغيل Linux مثال FreeBSD، وبدلاً من إجراء تغييرات على التعليمات البرمجية، قاموا بإعداد أداة إضافية للتعهد.com تسمح لك بتطبيق القيود دون تغيير رمز التطبيق. على سبيل المثال، لتشغيل الأداة المساعدة cur مع إمكانية الوصول فقط إلى فئات استدعاء النظام stdio وrpath وinet وthreadstdio، فقط قم بتشغيل "./pledge.com -p 'stdio rpath inet thread' curl http://example.com".

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

لا يتطلب التنفيذ إجراء تغييرات على kernel - تتم ترجمة قيود التعهد إلى قواعد SECCOMP BPF ومعالجتها باستخدام آلية عزل استدعاء نظام Linux الأصلي. على سبيل المثال، سيتم تحويل تعهد الاستدعاء ("stdio rpath"، 0) إلى مرشح BPF static const struct sock_filter kFilter[] = { /* L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, syscall, 0, 14 - 1) ), / * L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0]))), /* L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 2, 4 - 3, 0), /* L3* / BPF_JUMP( BPF_JMP | BPF_JEQ | BPF_K, 10, 0, 13 - 4), /* L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1]))), /* L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, ~0x80800), /* L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 1, 8 - 7, 0), /* L7*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 2, 0, 13 - 8) , /* L8*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])), /* L9*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 12 - 10, 0), /*L10*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 6, 12 - 11, 0), /*L11*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 17, 0, 13 - 11), /*L12*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), /*L13*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr))), /*L14*/ /* عامل التصفية التالي */ };

المصدر: opennet.ru

إضافة تعليق