خلال عملية مناقشة المطور من نواة لينكس حول ول موضوع مجموعة من بقع لإصلاح نقاط الضعف من Specter في الكود للعمل مع القوائم المرتبطة ، أصبح واضحا للعديد من المطورين أن هذه المشكلة يمكن حلها بسهولة أكبر إذا كان مسموحًا به في كود النواة C quيتوافق e مع إصدار أحدث من المعيار.
وهو أن الكود المضاف حاليًا إلى Linux Kernel يجب أن يتوافق مع مواصفات ANSI C (C89) التي تم تشكيلها في عام 1989.
هذا هو السبب المشكلة المتعلقة Specter في الكود كان بسبب sاستمر e باستخدام مكرر يتم تعريفها بشكل منفصل بعد الحلقة.
على الرغم من طبيعته السريعة بشكل عام ، يعتمد مشروع kernel على عدد من الأدوات القديمة. بينما يحب النقاد التركيز على الاستخدام المكثف للمجتمع للبريد الإلكتروني ، فإن المفارقة التاريخية الأكثر أهمية هي استخدام إصدار 1989 من معيار لغة C لرمز النواة ، وهو معيار تم تدوينه قبل بدء مشروع kernel منذ أكثر من 30 عامًا. يبدو أن هذه الممارسة طويلة الأمد قد تنتهي بمجرد النواة 5.18 ، والمتوقعة في مايو من هذا العام.
يذكر أن يتم استخدام الماكرو للتكرار على عناصر القائمة المرتبطة ، ونظرًا لتمرير مكرر الحلقة إلى هذا الماكرو ، يتم تعريفه خارج الحلقة نفسها ويظل متاحًا بعد الحلقة. سيسمح استخدام معيار C99 للمطورين بتحديد متغيرات الحلقة في كتلة for () ، والتي من شأنها حل المشكلة دون اختراع حلول بديلة.
لسوء الحظ ، هناك مواقع متعددة في kernel حيث القائمة
مكرر يستخدم بعد الحلقة التي تقطع على مثل هذا التغيير. لحسن الحظ
هناك البرنامج النصي use_after_iter.cocci الذي يمكن استخدامه لتحديد ذلك
مواقع الكود. اضطررت إلى تعديل البرنامج النصي قليلاً لأنه يقلل من الخطأ
الإيجابيات في حالة الاستخدام الأصلية ، ولكنها ذات صلة بهذا التصحيح.تستخدم مجموعة كبيرة ومتنوعة من مواقع التعليمات البرمجية التي تم الإبلاغ عنها فقط مكرر القائمة بعد ذلك
الدورة إذا كان هناك خروج مبكر (استراحة / الانتقال) وبالتالي فهي ليست كذلك
ذو صلة.
من جانبها، وافق لينوس تورفالدس على الفكرة لتكون قادرًا على تنفيذ الدعم للمواصفات الأحدث واقترح أيضًا الانتقال إلى kernel 5.18 لاستخدام معيار C11 ، الذي تم إصداره في عام 2011.
بعد ذلك ، أثناء التحقق الأولي ، مر التصاعد إلى GCC و Clang في الوضع الجديد دون انحراف. ما لم تظهر مشاكل غير متوقعة بسبب اختبارات أكثر شمولاً ، فإن نصوص بناء النواة 5.18 ستغير الخيار "–std = gnu89" إلى "–std = gnu11 -Wno-shift-negative-value".
لم يحب Linus Torvalds التصحيح كثيرًا ولم ير كيف يرتبط بنقاط ضعف التنفيذ التخمينية. ومع ذلك ، بعد أن أوضح Koschel الموقف بشكل أكبر ، وافق Torvalds على أن "هذا مجرد خطأ عادي ، واضح وبسيط" وقال إنه يجب إصلاحه بغض النظر عن السلسلة الأكبر. لكنه بعد ذلك تعمق في المصدر الحقيقي للمشكلة: أن المكرر الذي تم تمريره إلى قائمة ماكرو اجتياز القائمة يجب أن يُعلن عنه في نطاق خارج الحلقة نفسها:
السبب الرئيسي لحدوث هذا النوع من الأخطاء غير التأملية هو أنه تاريخيًا لم يكن لدينا نمط C99 "إعلان المتغيرات في الحلقات". لذا ، فإن list_for_each_entry () - وجميع الآخرين - تقوم دائمًا بتصفية آخر إدخال HEAD من الحلقة ، وذلك ببساطة لأننا لم نتمكن من إعلان متغير المكرر في الحلقة نفسها.
ومن الجدير بالذكر أن تم النظر في إمكانية استخدام معيار C17 ، ولكن في هذه الحالة ، سيكون من الضروري زيادة الحد الأدنى من الإصدار المدعوم من GCC ، نظرًا لأن تضمين دعم C11 يتوافق مع المتطلبات الحالية لإصدار GCC (5.1).
أخيرا إذا كنت مهتمًا بمعرفة المزيد عنها، يمكنك التحقق من التفاصيل في الرابط التالي.