STACKLEAK هي ميزة أمان kernel Linux تم تطويرها في الأصل من قبل منشئي Grsecurity / PaX. قررت إحضار STACKLEAK إلى نواة الفانيليا الرسمية (خط نواة لينكس الرئيسي). ستتحدث هذه المقالة عن البنية الداخلية وخصائص وظيفة الأمان ومسارها الصعب الطويل للغاية في الخط الرئيسي.

يحمي STACKLEAK من عدة فئات من نقاط الضعف في نواة Linux ، وهي:
- يقلل من المعلومات المفيدة للمهاجم ، والتي يمكن تسريبها من المكدس النووي إلى مساحة المستخدم ؛
- يمنع بعض الهجمات على المتغيرات غير المهيأة في حزمة النواة ؛
- يوفر أدوات الكشف عن تجاوز سعة مكدس ديناميكي.
تتناسب ميزة الأمان هذه تمامًا مع مفهوم مشروع Kernel للحماية الذاتية (KSPP): الأمان هو أكثر من مجرد إصلاح الأخطاء. لا يمكن إصلاح جميع الأخطاء في التعليمات البرمجية ، وبالتالي يجب أن تعمل نواة Linux بأمان في حالات الخطأ ، بما في ذلك عند محاولة استغلال الثغرات الأمنية. مزيد من التفاصيل حول KSPP
متوفرة على ويكي المشروع .
STACKLEAK موجود كـ PAX_MEMORY_STACKLEAK في تصحيح grsecurity / PaX. ومع ذلك ، فقد توقف توزيع التصحيح grsecurity / PaX بحرية منذ أبريل 2017. لذلك ، فإن ظهور STACKLEAK في نواة الفانيليا سيكون مفيدًا لمستخدمي Linux الذين لديهم متطلبات أمان معلومات متزايدة.
أمر العمل:
- حدد STACKLEAK من تصحيح grsecurity / PaX ،
- ادرس الكود بحرص وشكل رقعة
- إرسال إلى LKML ، والحصول على تعليقات ، وتحسين ، وتكرار مرة أخرى قبل قبولها في الخط الرئيسي.
في وقت كتابة هذا التقرير (25 سبتمبر 2018) ، تم إرسال
الإصدار 15 من سلسلة من التصحيحات . يحتوي على جزء مستقل ورمز مستقل لـ x86_64 و x86_32. تمكن دعم STACKLEAK لـ arm64 ، الذي طورته لورا أبوت من Red Hat ، من الوصول إلى نواة الفانيليا 4.19.
STACKLEAK: ميزات الأمان
مسح المعلومات المتبقية في حزمة النواة
يقلل هذا الإجراء من المعلومات المفيدة التي قد تنتجها بعض التسريبات من المكدس النووي إلى مساحة المستخدم.
يتم عرض مثال على تسرب المعلومات من مكدس kernel في الشكل 1.
مخطط 1.ومع ذلك ، تصبح التسريبات من هذا النوع عديمة الفائدة إذا تم ملء الجزء المستخدم من مكدس kernel بقيمة ثابتة (الشكل 2) في نهاية استدعاء النظام.

مخطط 2.
نتيجة لذلك ، يمنع STACKLEAK بعض الهجمات على المتغيرات غير المهيأة في مكدس النواة. أمثلة على نقاط الضعف هذه: CVE-2017-17712 ، CVE-2010-2963. يمكننا العثور على وصف لمنهجية الاستغلال لضعف CVE-2010-2963
في مقال كتبه Kees Cook.
يظهر جوهر الهجوم على متغير غير مهيأ في مكدس النواة في الشكل 3.
مخطط 3.يقوم STACKLEAK بحظر الهجمات من هذا النوع ، حيث تشير القيمة التي تملأ المكدس النووي في نهاية استدعاء النظام إلى منطقة غير مستخدمة في مساحة العنوان الظاهري (الشكل 4).
مخطط 4.أحد القيود الهامة هو أن STACKLEAK لا يحمي من الهجمات المماثلة التي تتم في استدعاء نظام واحد.
كشف تجاوز سعة المكدس الأساسي في kernel
في نواة الفانيليا (خط نواة لينكس الرئيسي) STACKLEAK فعال ضد تجاوز عمق مكدس kernel فقط بالاشتراك مع CONFIG_THREAD_INFO_IN_TASK و CONFIG_VMAP_STACK. يتم تنفيذ كل من هذه التدابير من قبل أندي Lutomirski.
يظهر الشكل 5 أبسط نسخة من استغلال هذا النوع من الضعف.
مخطط 5.يمكن أن يؤدي استبدال حقول معينة في بنية thread_info في أسفل المكدس النووي إلى زيادة امتيازات العملية. ومع ذلك ، عند تمكين خيار CONFIG_THREAD_INFO_IN_TASK ، تتم إزالة هذه البنية من المكدس النووي ، مما يلغي الطريقة الموضحة لاستغلال الثغرة الأمنية.
هناك نسخة أكثر تقدمًا من هذا الهجوم وهي استبدال البيانات في منطقة ذاكرة مجاورة عن طريق الخروج من حدود المكدس. المزيد عن هذا النهج:
ينعكس هذا النوع من الهجوم في الشكل 6.
مخطط 6.الحماية في هذه الحالة هي CONFIG_VMAP_STACK. عند تمكين هذا الخيار ، يتم وضع صفحة ذاكرة خاصة (صفحة حماية) بجوار المكدس النووي ، مما يؤدي إلى الوصول إلى استثناء (الشكل 7).
مخطط 7.أخيرًا ، الخيار الأكثر إثارة للاهتمام لتجاوز المكدس بعمق هو هجوم مثل Stack Clash. تم
طرح الفكرة من
قبل Gael Delalleau في عام 2005.
في عام 2017 ، أعاد باحثون من شركة Qualys التفكير في الأمر ،
واصفين هذه التقنية بـ Stack Clash. والحقيقة هي أن هناك طريقة للقفز فوق صفحة الحماية واستبدال البيانات من منطقة ذاكرة مجاورة (الشكل 8). يتم ذلك باستخدام صفيف متغير الطول (VLA) ، يتحكم فيه المهاجم بحجمه.
مخطط 8.لمزيد من المعلومات حول STACKLEAK و Stack Clash ،
راجع مدونة grsecurity .
كيف تحمي STACKLEAK من المكدس Clash في المكدس النووي؟ قبل كل استدعاء للتخصيص () ، يتم التحقق من تجاوز سعة المكدس بعمق. إليك الرمز المقابل من الإصدار 14 من سلسلة التصحيح:
void __used stackleak_check_alloca(unsigned long size) { unsigned long sp = (unsigned long)&sp; struct stack_info stack_info = {0}; unsigned long visit_mask = 0; unsigned long stack_left; BUG_ON(get_stack_info(&sp, current, &stack_info, &visit_mask)); stack_left = sp - (unsigned long)stack_info.begin; if (size >= stack_left) { #if !defined(CONFIG_VMAP_STACK) && defined(CONFIG_SCHED_STACK_END_CHECK) panic("alloca() over the kernel stack boundary\n"); #else BUG(); #endif } }
ومع ذلك ، تم استبعاد هذه الوظيفة من الإصدار 15. كان هذا في المقام الأول بسبب
حظر لينوس تورفالدس المثير للجدل لاستخدام BUG_ON () في تصحيحات أمان نواة لينكس.
بالإضافة إلى ذلك ، أدت النسخة التاسعة من سلسلة التصحيح إلى مناقشة ، ونتيجة لذلك تقرر القضاء على جميع المصفوفات المتغيرة من نواة الخط الرئيسي. شارك حوالي 15 مطورًا في هذا العمل ، وسيتم
الانتهاء منه قريبًا.
تأثير الأداء على STACKLEAK
أعطي نتائج اختبار الأداء على x86_64. الجهاز: Intel Core i7-4770، 16 GB RAM.
الاختبار رقم 1 ، جذاب: بناء نواة لينكس على أساس معالج واحد
اختبار رقم 2 ، غير جذاب:
لذلك ، يعتمد تأثير STACKLEAK على أداء النظام على نوع الحمل. على وجه الخصوص ، يزيد عدد كبير من مكالمات النظام القصيرة النفقات العامة. T.O. يجب تقييم أداء STACKLEAK للحمل المخطط له قبل الإنتاج.
الجهاز الداخلي STACKLEAK
يتكون STACKLEAK من:
- الكود الذي يمسح مكدس النواة في نهاية استدعاء النظام (مكتوب في الأصل في المجمع) ،
- البرنامج المساعد دول مجلس التعاون الخليجي لتجميع مفيدة لرمز النواة.
يتم مسح رصة kernel في دالة stackleak_erase (). يتم تنفيذ هذه الوظيفة قبل العودة إلى مساحة المستخدم بعد استدعاء النظام. تتم كتابة STACKLEAK_POISON (-0xBEEF) إلى الجزء المستخدم من مكدس مؤشر الترابط. يشير متغير أدنى_ستاك ، يتم تحديثه باستمرار في stackleak_track_stack () ، إلى نقطة بدء التنظيف.
تنعكس مراحل stackleak_erase () في المخططين 9 و 10.
مخطط 9.
مخطط 10.T.O. يقوم stackleak_erase () بمسح الجزء المستخدم فقط من المكدس النووي. هذا هو السبب في أن STACKLEAK سريع جدًا. وإذا قمت بمسح كل 16 كيلو بايت من مكدس kernel على x86_64 في نهاية كل استدعاء للنظام ، يظهر hackbench انخفاضًا في الأداء بنسبة 40٪.
يتم إجراء الأجهزة الخاصة بكود النواة في مرحلة التجميع في البرنامج المساعد STACKLEAK GCC.
الإضافات الخليجية عبارة عن وحدات قابلة للتنزيل خاصة بالمشروع للمترجم الخليجي. يسجلون تصاريح جديدة مع مدير تصاريح دول مجلس التعاون الخليجي ، ويقدمون الاسترجاعات لهذه التصاريح.
لذلك ، بالنسبة لعملية STACKLEAK الكاملة ، يتم إدراج الاستدعاءات إلى stackleak_track_stack () في كود الوظائف مع إطار مكدس كبير. أيضًا ، قبل كل تخصيص () ، يتم إدراج استدعاء إلى stackleak_check_alloca () المذكور بالفعل ، وبعد ذلك ، يتم إدراج استدعاء إلى stackleak_track_stack ().
كما ذكرنا من قبل ، في الإصدار 15 من سلسلة التصحيح ، تم استبعاد إدراج المكالمات إلى stackleak_check_alloca () من البرنامج المساعد GCC.
المسار في نواة لينكس الرئيسية
مسار STACKLEAK في الخط الرئيسي طويل وصعب للغاية (الشكل 11).
مخطط 11. التقدم المحرز في تنفيذ STACKLEAK في الخط الرئيسي لنواة لينكس.في أبريل 2017 ، أغلق منشئو grsecurity بقعهم على المجتمع ، وبدأوا في توزيعها على أساس تجاري فقط. في مايو 2017 ، قررت تولي مهمة إدخال STACKLEAK في قلب الفانيليا. وهكذا بدأت رحلة أطول من عام. تمنحني شركة التقنيات الإيجابية ، التي أعمل فيها ، الفرصة للتعامل مع هذه المهمة لبعض وقتي من العمل. ولكن في الأساس ، أقضي وقتًا "مجانيًا" في ذلك.
منذ شهر مايو الماضي ، خضعت سلسلة التصحيح الخاصة بي لمراجعات متعددة ، خضعت لتغييرات كبيرة ، تم انتقادها مرتين من قبل لينوس تورفالدس. أردت أن أترك هذا الأمر كله عدة مرات. ولكن في لحظة معينة كانت هناك رغبة قوية للوصول إلى النهاية. في وقت كتابة هذا التقرير (25 سبتمبر 2018) ، كان الإصدار الخامس عشر من سلسلة التصحيح في الفرع التالي لينكس ، ويلبي جميع المتطلبات المعلنة للينوس وهو جاهز لنافذة الدمج للنواة 4.20 / 5.0.
قبل شهر ، تحدثت عن هذا العمل في قمة أمان Linux. أقدم روابط
للشرائح ومقاطع الفيديو :
الخلاصة
STACKLEAK هي ميزة أمان نواة Linux مفيدة جدًا تمنع استغلال العديد من أنواع الثغرات في وقت واحد. بالإضافة إلى ذلك ، تمكن المؤلف الأصلي لفريق PaX من جعله سريعًا وجميلًا في الهندسة. لذلك ، فإن ظهور STACKLEAK في نواة الفانيليا سيكون مفيدًا لمستخدمي Linux الذين لديهم متطلبات أمان معلومات متزايدة. علاوة على ذلك ، يلفت العمل في هذا الاتجاه انتباه مجتمع مطوري Linux إلى أدوات الدفاع عن النفس kernel.
ملاحظة
تم اعتماد STACKLEAK في النهاية بواسطة نواة Linux 4.20:
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/؟id=2d6bb6adb714b133db92ccd4bfc9c20f75f71f3fالبنيات المدعومة هي x86_64 و x86_32 و arm64.
بالإضافة إلى ذلك ، تم الانتهاء من العمل للقضاء على المصفوفات متغيرة الطول من كود نواة لينكس. تم تضمين تحذير مترجم Gcc "-Wvla" في إصدار kernel 4.20:
lkml.org/lkml/2018/10/28/189