تسليط الضوء على الزركون: vDSO (كائن ديناميكي مشترك افتراضي)

الزركون؟ ما هذا


في أغسطس 2016 ، دون أي إعلانات رسمية من Google ، تم اكتشاف مصادر نظام التشغيل الجديد الفوشيه. يعتمد نظام التشغيل هذا على نواة صغيرة تسمى Zircon ، والتي تعتمد بدورها على LK (Little Kernel) .


الفوشيه ليس لينكس

ملاحظات المترجم

انا لا لحام حقيقي أنا مطور و / أو خبير في الزركون. النص الموجود أسفل المقطع عبارة عن مجموعة من الترجمات الجزئية: وثائق Zircon vDSO الرسمية والمقالة الإعجاب بالزركون الجزء 1: فهم إنشاء عملية بسيطة من depletionmode ، حيث تمت إضافة هفوة صغيرة (تمت إزالتها للمفسدين). لذلك ، اقتراحات بناءة لتحسين المقال ، كما هو الحال دائما ، هي موضع ترحيب.


ما الذي سيتم مناقشته في المقال؟


vDSO في الزركون هو الوسيلة الوحيدة للوصول إلى مكالمات النظام (syscalls) .


هل من المستحيل حقًا الاتصال مباشرة بتعليمات المعالج SYSENTER / SYSCALL من التعليمات البرمجية الخاصة بنا؟ لا ، هذه التعليمات المعالج ليست جزءًا من نظام ABI. يحظر رمز المستخدم لاتباع هذه التعليمات مباشرة.


أولئك الذين يرغبون في معرفة المزيد من التفاصيل حول هذه الخطوة المعمارية ، أدعوك إلى Cat.



الزركون vDSO (كائن مشترك ديناميكي افتراضي)


vDSO في اختصار لتقف على v ظاهري D ynamic S hared O bject:


  • الكائن الديناميكي المشترك هو مصطلح يستخدم للإشارة إلى المكتبات المشتركة لتنسيق ELF (ملفات .so).
  • هذا الكائن افتراضي لأنه لا يتم تحميله من ملف منفصل موجود على نظام الملفات. يتم توفير صورة vDSO مباشرة بواسطة النواة.

دعم النواة


يتم تطبيق دعم vDSO باعتباره ABI المتحكم فيه فقط للتطبيقات في وضع المستخدم بطريقتين:


  1. إسقاط كائن الذاكرة الظاهرية ( VMO ، كائن الذاكرة الظاهرية ).

    عندما يعالج zx_vmar_map VMO لـ vDSO ( ZX_VM_PERM_EXECUTE في الوسيطات) ، تتطلب النواة أن تتوافق الإزاحة والحجم مع مقطع vDSO القابل للتنفيذ بشكل صارم. يضمن هذا (بما في ذلك) إسقاط vDSO واحد فقط في ذاكرة العملية. بعد أول إسقاط ناجح لـ vDSO في العملية ، لم يعد من الممكن حذفه. ومحاولة لإعادة مشروع vDSO في ذاكرة العملية ، ومحاولات حذف VMO المسقطة لـ vDSO أو المشروع مع الإزاحة الخاطئة و / أو فشل الحجم مع الخطأ ZX_ERR_ACCESS_DENIED .
    يتم استخراج إزاحة وحجم رمز vDSO في مرحلة التحويل البرمجي من ملف ELF ، ثم يتم استخدامه في كود kernel لإجراء الاختبارات المذكورة أعلاه. بعد أول إسقاط ناجح لـ vDSO ، يتذكر kernel OS عنوان العملية المستهدفة من أجل تسريع عمليات الفحص.


  2. تحقق من عناوين الإرجاع لوظائف استدعاء النظام.

    عندما يستدعي رمز وضع المستخدم النواة ، يتم إرسال رقم استدعاء نظام منخفض المستوى في السجل. مكالمات النظام منخفضة المستوى هي الواجهة الداخلية (الخاصة) بين vDSO وجوهر الزركون. بعض (معظم) تتوافق مباشرة مع مكالمات النظام من ABI العامة ، في حين أن البعض الآخر لا.
    لكل مكالمة نظام منخفض المستوى في كود vDSO ، هناك مجموعة ثابتة من الإزاحات في الكود الذي يقوم بهذه المكالمة. يحدد مصدر شفرة vDSO الأحرف الداخلية التي تحدد كل موقع من هذا القبيل. في وقت الترجمة ، يتم استرداد هذه المواقع من جدول رموز vDSO وتستخدم لإنشاء رمز kernel الذي يحدد التنبؤ بصلاحية عنوان الرمز لكل مكالمة نظام منخفضة المستوى. تتيح لك هذه التنبؤات التحقق بسرعة من رمز الاتصال للتأكد من صحته ، بالنظر إلى الإزاحة من بداية مقطع شفرة vDSO.
    إذا تم تحديد ذلك وفقًا للتنبؤ بأنه لا يُسمح لرمز الاتصال بإجراء مكالمة نظام ، يتم طرح استثناء اصطناعي ، كما لو أن رمز الاتصال حاول تنفيذ تعليمة غير موجودة أو مميزة.



vDSO عند إنشاء عملية جديدة


لبدء تنفيذ مؤشر الترابط الأول لعملية تم إنشاؤها حديثًا ، يتم استخدام استدعاء النظام zx_process_start . المعلمة الأخيرة من استدعاء النظام هذا (راجع arg2 في الوثائق) بتمرير الوسيطة لمؤشر الترابط الأول للعملية التي تم إنشاؤها. وفقًا للاتفاقية المقبولة ، يقوم برنامج تحميل البرنامج بتخطيط vDSO إلى مساحة العنوان الخاصة بالعملية الجديدة (إلى مكان عشوائي يحدده النظام) وينقل العنوان الأساسي للتعيين مع وسيطة arg2 إلى الخيط الأول من العملية التي تم إنشاؤها. هذا العنوان هو عنوان رأس ملف ELF ، حيث يمكن العثور على الوظائف المسماة اللازمة لإجراء مكالمات النظام.


بطاقة الذاكرة (تخطيط) vDSO


vDSO هي مكتبة مشتركة EFL منتظمة يمكن اعتبارها مثل أي مكتبة أخرى. ولكن بالنسبة لـ vDSO ، يتم تحديد مجموعة فرعية صغيرة من تنسيق ELF بأكمله عن قصد. هذا له العديد من المزايا:


  • إن عملية تعيين ELF هذه في العملية بسيطة ولا تتضمن أي حالات حدود معقدة مطلوبة لدعم برامج ELF بالكامل.
  • لا يتطلب استخدام vDSO ربط ELF ديناميكي كامل الوظائف. على وجه الخصوص ، ليس لدى vDSO عمليات نقل ديناميكية. يعد عرض شرائح PT_LOAD لملف ELF هو الإجراء الوحيد المطلوب.
  • رمز vDSO هو عديمي الجنسية و reentrant. إنه يعمل حصريًا مع سجلات المعالج والمكدس. هذا يجعله مناسبًا للاستخدام في مجموعة متنوعة من السياقات مع الحد الأدنى من القيود ، والذي يتوافق مع نظام التشغيل ABI الإلزامي. كما أنه يبسط تحليل الشفرة والتحقق من الموثوقية والأمان.

يتم تمثيل جميع ذاكرة vDSO بشريحتين متتاليتين ، يحتوي كل منهما على صفحات كاملة محاذية:


  1. الجزء الأول للقراءة فقط ويتضمن رؤوس ELF بالإضافة إلى بيانات ثابتة.
  2. الجزء الثاني قابل للتنفيذ ويحتوي على رمز vDSO.

تتكون صورة vDSO بأكملها من صفحات هذين القطاعين فقط. يلزم فقط قيمتين مستخرجتين من رؤوس ELF لعرض ذاكرة vDSO: عدد الصفحات في كل مقطع.


نظام التشغيل وقت التمهيد البيانات الثابتة


تقوم بعض استدعاءات النظام ببساطة بإرجاع قيم ثابتة (يجب طلب القيم في وقت التشغيل ولا يمكن تجميعها في رمز وضع المستخدم). يتم إصلاح هذه القيم في kernel في وقت الترجمة ، أو يتم تحديدها بواسطة kernel في وقت التمهيد (معلمات التمهيد ومعلمات الأجهزة). على سبيل المثال: zx_system_get_version () و zx_system_get_num_cpus () و zx_ticks_per_second () . تتأثر قيمة الإرجاع للدالة الأخيرة ، على سبيل المثال ، بمعلمة سطر أوامر kernel .


انتظر ، هل عدد وحدات المعالجة المركزية ثابت؟

ومن المثير للاهتمام ، أن وصف الدالة zx_system_get_num_cpus () ينص صراحة أيضًا على أن نظام التشغيل لا يدعم الاستبدال السريع لعدد المعالجات:


لا يمكن تغيير هذا الرقم أثناء تشغيل النظام ، إلا في وقت التمهيد.

يشير هذا ، على الأقل ، بشكل غير مباشر إلى أن نظام التشغيل لم يتم وضعه كخادم.


نظرًا لأن هذه القيم ثابتة ، فلا معنى للدفع مقابل مكالمات النظام الحقيقية إلى kernel OS. بدلاً من ذلك ، يكون تنفيذها عبارة عن وظائف C ++ بسيطة تقوم بإرجاع البيانات من مقطع vDSO الثابت. يتم تجميع القيم التي تم التقاطها أثناء التحويل البرمجي (مثل سلسلة إصدار النظام) ببساطة إلى vDSO.


بالنسبة للقيم المحددة في وقت التمهيد ، يجب أن يقوم kernel بتعديل محتويات vDSO. يتم ذلك باستخدام تعليمات برمجية قابلة للتنفيذ مبكرًا تشكل VMO vDSO قبل أن يبدأ kernel عملية المستخدم الأولى (ويمررها واصف VMO). أثناء التحويل البرمجي ، يتم استخراج الإزاحة من صورة vDSO ( vdso_constants ) من ملف ELF ثم دمجها في kernel. وفي وقت التمهيد ، تعرض kernel مؤقتًا الصفحات التي تغطي vdso_constants في مساحة العنوان الخاصة بها لتهيئة الهيكل مسبقًا بالقيم الصحيحة (لبدء تشغيل النظام الحالي).


لماذا كل هذا الصداع ؟


أحد أهم الأسباب هو الأمن. أي إذا تمكن المهاجم من تنفيذ تعليمة تعسفية (shell) ، فسيتعين عليه استخدام وظائف vDSO لاستدعاء وظائف النظام. ستكون العقبة الأولى هي التوزيع العشوائي المذكور أعلاه لعنوان التمهيد vDSO لكل عملية تم إنشاؤها. ونظرًا لأن OS kernel مسؤول عن VMO الخاص بـ (كائن الذاكرة الظاهرية) الخاص بـ vDSO ، فيمكنه اختيار تعيين vDSO مختلف تمامًا لعملية معينة ، وبالتالي حظر استدعاءات نظام خطيرة (وغير مطلوبة لعملية معينة). على سبيل المثال: يمكنك منع برامج التشغيل من إنشاء عمليات تابعة أو التعامل مع مناطق MMIO الخاصة بالإسقاط. هذه أداة رائعة لتقليل سطح الهجوم.


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


ماذا عن أنظمة التشغيل الأخرى؟

تجدر الإشارة إلى أنه تم بالفعل استخدام تقنيات مماثلة بنجاح في أنظمة التشغيل الأخرى. على سبيل المثال ، يوجد في نظام Windows ProcessSystemCallDisablePolicy :


Win32k System Call Disable Restriction لتقييد القدرة على استخدام NTUser و GDI

Source: https://habr.com/ru/post/ar435482/


All Articles