
استغلال CVE-2021-3679 وتوثيق إصلاحه
هذا برنامج إثبات مفهوم (PoC) لتشغيل بهدف إثبات خطأ منطقي في rb_per_cpu_empty. البرامج التي تصطدم بالخطأ ستعلق في حلقة ميتة مشغولة في نواة النظام (kernel-space) في tracing_read_pipe وسيكون من المستحيل تعليقها أو إنهاؤها باستخدام أي إشارة UNIX (بما في ذلك SIGKILL).
على الرغم من أنه يُظهر سلوكًا مشابهًا (حلقة ميتة واستنزاف لوحدة المعالجة المركزية) لخطأ حساب seq_buf_used الذي تم إصلاحه في لينكس 4.5، فإن هذا البرنامج يهدف إلى إثبات وجود خطأ آخر له سبب مختلف تمامًا ويُعتقد أنه موجود في نوى لينكس من الإصدار 3.10 إلى 5.14-rc1 (انظر أيضًا نتيجة تنفيذ PoC).
إخلاء المسؤولية: قد يؤدي برنامج إثبات المفهوم هذا إلى تعليق نظام لينكس لديك، واستنزاف كمية كبيرة من الطاقة، ولا يمكن إنهاؤه باستخدام إشارة UNIX عند الاصطدام به، استخدمه على مسؤوليتك الخاصة.
يجب تثبيت هذه الحزم أو الأوامر قبل تنفيذ سكريبت إثبات المفهوم.
gcc
realpath
nm
كما أن أوامر باش (Bash) ومعالجة السلاسل مثل awk و grep مطلوبة، ومن المحتمل أن تكون موجودة في توزيعاتك.
على الرغم من أنه سكريبت باش، إلا أن جزء الكود الذي يحدد uprobe يعتمد على المنصة (لا يمكننا استخدام $argN في uprobe)، ونحن ندعم i386 و x86_64 و arm و aarch64. لا تتردد في إضافة دعم المنصة الخاصة بك.
لتشغيل إثبات المفهوم، فقط نفذ الأمر التالي بصلاحية الجذر (root):
./rbdetonate

إذا تم تشغيل الخطأ بواسطة إثبات المفهوم، سيتم إنشاء عملية dd تستهلك نواة كاملة لوحدة المعالجة المركزية، ولا يمكن قتلها باستخدام إشارة UNIX مثل SIGKILL فقط.
يمكن قتل عملية bash الخاصة بسكريبت rbdetonate، لكن إرسال إشارة SIGINT قد يؤدي إلى إنهائها أو لا، اعتمادًا على تطبيق bash. ولا يمكن قتل الإصدارات الأحدث من bash بإشارة SIGINT إلا عندما تكون عملية dd المنشأة قيد التشغيل.

قد يخرج rbdetonate ويطبع Nothing buggy has been detected إذا لم يتمكن من إنشاء عملية dd بعد عدة محاولات. ومع ذلك، قد يستغرق هذا بعض الوقت بسبب إعادة المحاولة 8192 مرة.
تعليق: هذا الخطأ موجود نظريًا في جميع الإصدارات التي تحتوي على ميزة تتبع مساحة المستخدم (>=3.10)، لكن الإصدارات الأقدم من النواة لا تعمل uprobe بشكل صحيح بعدة طرق. سيكون موضع تقدير إذا كنت تستطيع مساعدتنا في تصحيح سلوكها.
ج: فقط نفذ الأمر التالي
echo > /sys/kernel/debug/tracing/instances/rbdetonate/trace
بصلاحية الجذر يجب أن يخرج البرنامج من الحلقة الميتة.
ج: لا. أدوات البناء المستخدمة هنا هي فقط لبناء برنامج rbwrite، الذي ينتج نتيجة حتمية بمجرد الكتابة إلى صفحات المخزن المؤقت الحلقي على CPU#0، وفقًا لخطواتنا المصممة.
بساطة بالنسبة لإثبات المفهوم هذا، يمكن أيضًا استخدام نسخة مترجمة من برنامج rbwrite، ويمكن استرداد عنوان نقطة التتبع (tracepoint) بعد ذلك.
لاستخدام تتبع لينكس، إذا كنت لا تمانع الضوضاء الناتجة عن التطبيقات، فإن إضافة نقاط تتبع kprobe إلى استدعاءات النظام ووظائف النواة ستولد أيضًا أحداثًا. لكن بالنسبة لإثبات المفهوم، قد يؤدي هذا إلى عدم الحتمية (undeterminism) وهو غير مفضل.
| الإصدار | تم إعادة إنتاجه | لقطة الشاشة |
|---|
| 5.14.0-rc2-00479-g86020194bc7e (Fix version) | N | 5.14.0-rc2-00479-g86020194bc7e.png |
| 5.14.0-rc2-00478-g2734d6c1b1a0 (5.14.0-rc2) | Y | 5.14.0-rc2-00478-g2734d6c1b1a0.png |
| 5.4.0-77-generic | Y | 5.4.0-77-generic.png |
| 4.4.0-142-generic | Y | 4.4.0-142-generic.png |