
إفشاء عام لثغرة CVE-2026-43655 AppleM2ScalerCSCDriver use-after-free
إفصاح تقني عام عن CVE-2026-43655، وهو خطأ استخدام بعد التحرير (use-after-free) في AppleM2ScalerCSCDriver / IOSurfaceAccelerator يمكن الوصول إليه من حاوية تطبيقات iOS الافتراضية دون تراخيص خاصة.
عالجت Apple هذه المشكلة في iOS 26.5 / iPadOS 26.5 / macOS Tahoe 26.5. يحتوي هذا المستودع على كود الإثبات (proof-of-concept) بلغة Objective-C، والتراخيص الدنيا، وملف IPA مُجمَّع، والشرح الفني اللازم لفهم وإعادة إنتاج المشكلة على جهاز متأثر.
الخلل هو خطأ في دورة حياة/إزالة جدولة المقاييس (scaler scheduler). يمكن لعملية مستخدم إرسال عمليات مقاييس غير متزامنة، وإغلاق الاتصال IOSurfaceAcceleratorClient الذي يملك تلك العمليات، تاركةً إدخالات قديمة في هيكل الجدولة العام للسائق. يمكن لتمريرة جدولة لاحقة معالجة إدخالات لا تزال تشير إلى تخزين العمليات الذي تم تحريره بالفعل وإعادة استخدامه.
يُظهر الإثبات (PoC) خطأ دورة الحياة بقيمتين مميزتين:
0xDEAD00010xBEEF0002يقوم اتصال الضحية بإرسال عمليات غير متزامنة ثم يُغلق. تُفتح اتصالات بديلة بعد ذلك وتضبط علامتها إلى 0xBEEF0002. عندما تعمل دورة الجدولة التالية للمقياس، يقرأ الخطأ العلامة البديلة (x9 = 0x00000000BEEF0002) بدلاً من علامة الضحية. وهذا يثبت أن الجدولة قرأت من فتحة عملية تم تحريرها ثم تخصيصها لاتصال مختلف.
com.apple.driver.AppleM2ScalerCSCDriverIOSurfaceAcceleratorClientget-task-allow فقطيحتفظ AppleM2ScalerCSCDriver بحالة جدولة مشتركة عبر عملاء المقياس. عدم التطابق في دورة الحياة ذو الصلة هو:
IOServiceClose.لا يزيل مسار الإزالة إدخالات الجدولة المعلقة للعميل المُغلق من كومة الجدولة المشتركة. تقرأ الجدولة لاحقًا وتكتب حقولاً عبر تلك المؤشرات القديمة.
الحقول الهامة التي تمت ملاحظتها أثناء التحليل:
| الإزاحة | سلوك الجدولة |
|---|---|
operation + 0xc94 | يُقرأ كقيمة الائتمان/العلامة المستخدمة من قبل مسار حل الائتمان |
operation + 0xc1c | يُكتب بواسطة مسار محاسبة ائتمان الجدولة |
operation + 0x1fe4 | يُكتب بواسطة مسار تحديث حالة/علم الجدولة |
السلوك المُخصص للعمليات يجعل الخلل قابلاً للملاحظة: يمكن إعادة استخدام فتحات العمليات المحررة بواسطة عمليات لاحقة من اتصالات مختلفة. عن طريق إغلاق اتصال الضحية ورش اتصالات جديدة فورًا، يمكن للإثبات جعل إدخالات الجدولة القديمة تشير إلى ذاكرة أصبحت الآن مملوكة لاتصالات الرش.
x9 = 0xBEEF0002 استخدام بعد التحرير (UAF)يستخدم الإثبات تمييزًا بين الضحية والرش:
0xDEAD0001.0xBEEF0002.إذا كانت الجدولة لا تزال تقرأ من كائنات حية مملوكة للضحية، لكانت القيمة المرصودة 0xDEAD0001. بدلاً من ذلك، يقرأ الخلل المُعاد إنتاجه 0xBEEF0002، القيمة التي كتبتها اتصالات الرش البديلة. هذا هو الدليل الرئيسي على أن الجدولة تفك مرجعية مؤشر قديم إلى ذاكرة نواة تم تحريرها وإعادة استخدامها.
يظهر هذا أيضًا تأثيرًا عبر الاتصالات: تم إنشاء إدخال الجدولة بواسطة اتصال واحد، لكن الذاكرة التي لمسها لاحقًا تم إعادة تدويرها لاتصال آخر. في عمليات التشغيل المُعاد إنتاجها، يمكن أن يكون نشاط الجدولة النهائي مدفوعًا بنشاط SpringBoard/المركب/واجهة المستخدم العادي بدلاً من عملية الإثبات الأصلية.
يصف الإعلان العام من Apple التأثير بأنه: "قد يتمكن تطبيق من التسبب في إنهاء غير متوقع للنظام أو قراءة ذاكرة النواة."
تفصيل مهم لإعادة الإنتاج: بعد النقر على TEARDOWN UAF، لا يتوقف الجهاز بالضرورة فورًا. يقوم الإثبات أولاً بتهيئة حالة الجدولة القديمة. يحدث الخلل في دورة جدولة المقياس التالية، والتي تحدث عمليًا عندما يدفع نشاط SpringBoard/المركب المقياس. في إعادة الإنتاج على جهازي الفعلي، قمت بتفعيل دورة الجدولة تلك عن طريق النقر/التفاعل مع Dynamic Island بعد أن أنهى الإثبات تهيئة حالة الجدولة القديمة.
الخطوات:
ScalerTeardownUAF.ipa.AppleM2ScalerCSCDriver.IOSurface مصدر/وجهة.0xDEAD0001 على اتصال الضحية.IOServiceClose، محررًا كائنات عمليات مملوكة للضحية بينما تبقى إدخالات الجدولة القديمة.0xBEEF0002.x9 = 0x00000000BEEF0002.شرط الإثبات المتوقع:
x9 = 0x00000000BEEF0002 يعني أن الجدولة قرأت علامة الرش من الذاكرة التي كانت تنتمي أصلاً إلى عملية الضحية المحررة.0xBEEF0002 ليست علامة الضحية؛ إنها علامة اتصال البديل.يقوم المصدر المُضمن بتنفيذ التسلسل التالي:
open victim connection
create IOSurface source/destination pair
submit sync baseline scaler request
set victim marker = 0xDEAD0001 through selector 10
submit 50 async scaler operations
close victim connection
open 50 spray connections
set spray marker = 0xBEEF0002 through selector 10
submit repeated async scaler operations on spray connections
wait for SpringBoard/compositor scheduler trigger
ملف المصدر ذو الصلة هو ScalerTeardownUAF.m.
xcrun -sdk iphoneos clang -framework Foundation -framework UIKit -framework IOKit \
-framework IOSurface -isysroot $(xcrun --sdk iphoneos --show-sdk-path) \
-arch arm64 -arch arm64e -miphoneos-version-min=16.0 -fobjc-arc \
-o iPhoneProbe.app/iPhoneProbe ScalerTeardownUAF.m
ldid -S entitlements.plist iPhoneProbe.app/iPhoneProbe
mkdir -p /tmp/pkg/Payload
cp -r iPhoneProbe.app /tmp/pkg/Payload/
cd /tmp/pkg && zip -qr ScalerTeardownUAF.ipa Payload
| الملف | الوصف |
|---|---|
ScalerTeardownUAF.m | مصدر الإثبات بلغة Objective-C ينفذ تسلسل إغلاق الضحية + إعادة استخدام الرش. |
ScalerTeardownUAF.ipa | أثر إعادة الإنتاج بصيغة IPA مُجمعة. |
entitlements.plist | ملف التراخيص الأدنى يحتوي على get-task-allow. |