
Android GKI 6.12 उपकरणों पर CVE-2026-43499 का शोषण करता है: नियतात्मक मनमाना कर्नेल रीड/राइट, KASLR बाईपास, और LD_PRELOAD पेलोड के माध्यम से पूर्ण रूट।
Android GKI 6.12 लाइन (Samsung और Pixel डिवाइस) के लिए एक Linux कर्नेल शोषण, जो CVE-2026-43499 को लक्षित करता है: rt_mutex_start_proxy_lock() में एक बगी remove_waiter() रोलबैक जो waiter::task के बजाय current का उपयोग करता है, जिससे एक वेटर का pi_blocked_on उसके (बाद में पॉप किए गए) कर्नेल स्टैक rt_mutex_waiter की ओर इंगित करता रह जाता है। pselect() fd_set स्टैक ओवरराइट और एक कंज़्यूमर sched_setattr-चालित नकली rb_tree वॉक के साथ मिलकर, यह एक नियतात्मक कर्नेल राइट प्रिमिटिव और पूर्ण रूट प्राप्त करता है।
शोषण एक LD_PRELOAD शेयर्ड लाइब्रेरी (preload.so) के रूप में चलता है और रूट-पश्चात आर्टिफैक्ट के रूप में एक रूट su डेमन और वॉलपेपर स्थापित करता है।
स्थिति: सक्रिय विकास। प्रति-लक्ष्य स्टैक-गहराई ऑफसेट (
PSELECT_*वर्ड शिफ्ट) और स्लाइड व्यवहार डिवाइस के अनुसार भिन्न होते हैं और अभी भी डिवाइस पर सत्यापित किए जा रहे हैं। m1q (ZF1) लक्ष्य वर्तमान bring-up फोकस है।
जब FUTEX_CMP_REQUEUE_PI एक वेटर को requeue करता है और requeue की डेडलॉक-डिटेक्शन चेन वॉक -EDEADLK लौटाती है, तो __rt_mutex_start_proxy_lock() remove_waiter() (rtmutex.c:1535) के माध्यम से रोलबैक करता है। रोलबैक वेटर को वेट ट्री से सही ढंग से हटा देता है लेकिन waiter->task->pi_blocked_on के बजाय requeue करने वाले कॉलर का pi_blocked_on साफ़ करता है। वेटर का pi_blocked_on उसके स्टैक rt_mutex_waiter पर डैंगलिंग रहता है, जो फ्यूटेक्स के टाइमआउट होते ही पॉप हो जाता है।
टाइमआउट के बाद, वेटर का कर्नेल स्टैक क्षेत्र पुनः उपयोग किया जाता है: core_sys_select() तीन fd_sets को उस स्टैक बफर में कॉपी करता है (ZF1 पर nfds < 344 स्टैक पथ)। एक क्राफ्ट किया गया fd_set वर्ड ऐरे एक नकली rt_mutex_waiter / नकली टास्क / नकली rt_mutex (नियंत्रित पॉइंटर्स वाली rb_tree रूट के साथ) को पुनः निर्मित करता है। फिर एक कंज़्यूमर थ्रेड sched_setattr_tid(waiter) → rt_mutex_adjust_pi() → rb_erase_cached को कॉल करता है, जो एक नियंत्रित मान की आर्बिट्रेरी एड्रेस राइट उत्पन्न करता है।
पूरा प्रिमिटिव आवश्यक रूप से PI चेन चक्र पर निर्भर करता है: ओनर f_pi_target रखता है और f_pi_chain (वेटर द्वारा रखा गया) पर भी ब्लॉक करता है, इसलिए चेन वॉक ओनर → चेन → वेटर → टारगेट → ओनर तक पहुँचता है और -EDEADLK के साथ विफल हो जाता है। चक्र हटाने पर requeue शून्य कर्नेल प्रभाव के साथ सफलता लौटाता है।
sched_blocked_reason (m1q प्राथमिक): एक ब्लॉक किए गए kworker का सेव्ड रिटर्न PC (stack_trace_save_tsk) रिंग बफर से पढ़ा जाता है और संकलित worker_thread ऑफसेट के विरुद्ध तुलना किया जाता है।SLIDE_LOGGERS_0_1 को boot_id sysctl डेटा में डालता है; लीक किया गया मान stext का पुनर्निर्माण करता है।mm_struct-आकार की ऑब्जेक्ट्स को स्प्रे करें और हीप पर mm_struct का पता लगाने के लिए futex-हैश टकराव का उपयोग करें, जिससे नकली-ऑब्जेक्ट स्प्रे बेस के रूप में उपयोग किया जाने वाला कर्नेल हीप पेज एड्रेस लीक होता है।.data ashmem file_operations के write_iter स्लॉट (+0x30) में configfs_bin_write_iter लिखता है। फिर ashmem खोलने से configfs बाइनरी-fs पथ के माध्यम से आर्बिट्रेरी कर्नेल रीड/राइट प्राप्त होता है।वैकल्पिक STAGE3=1 चरण जो एक ब्रिज चाइल्ड को fork करता है, उसके mm->pgd को एक स्टेज किए गए नकली पेज टेबल (3-स्तरीय: PGD→L1→L2, RX लूप लीफ + RW स्टैक लीफ) में बदल देता है, और चाइल्ड को एक रजिस्टर-ओनली असेंबली ब्लॉब चलाने देता है जो 2MB भौतिक स्कैन विंडो के माध्यम से अपने स्वयं के cred को पैच करता है — configfs/pipe प्रिमिटिव के बिना ऑल-RAM फिजिकल R/W। वर्तमान में केवल m1q लक्ष्य में जोड़ा गया है और इसे डिवाइस पर नहीं चलाया गया है।
src/targets/<codename>-<build>/ में 41 लक्ष्य, प्रत्येक को न्यूनतम एक target.h की आवश्यकता होती है (कर्नेल सिंबल ऑफसेट, KIMAGE_TEXT_BASE, डायरेक्ट-मैप बेस, स्ट्रक्चर ऑफसेट)। Pixel लक्ष्य (comet, tokay, tegu, caiman, komodo, frankel, mustang, rango, stallion, blazer) साझा स्रोतों को ओवरराइड करते हैं; Samsung लक्ष्य (m1q-*) डिवाइस-विशिष्ट लॉजिक जोड़ते हैं।
make list-projects # full list
कर्नेल स्ट्रक्चर लेआउट डिवाइस के अनुसार भिन्न होते हैं — ऑफसेट को प्रत्येक लक्ष्य के लिए वास्तविक कर्नेल बाइनरी / kallsyms के विरुद्ध सत्यापित किया जाना चाहिए।
आउटपुट: build/<PROJECT>/bin/preload.so (LD_PRELOAD के माध्यम से लोड की गई शेयर्ड लाइब्रेरी)।
# Default project
CC=clang make
# Specific device target (default: blazer-CP2A.260605.012)
CC=clang make PROJECT=m1q-BP4A.251205.006
# Without CC=clang: uses NDK if found ($NDK_ROOT / $ANDROID_NDK_HOME /
# $ANDROID_NDK_ROOT), otherwise host clang + Android sysroot
make PROJECT=m1q-BP4A.251205.006
# Show build configuration
make info
# Clean
make clean
बिल्ड एक PIE su_daemon बाइनरी (src/su_daemon.c, build/embed/su_daemon_aarch64_pie में निर्मित) और assets/wallpaper.webp को src/su_blob.S / src/wallpaper_blob.S के माध्यम से preload.so में एम्बेड करता है।
बिल्ड आउटपुट को /data/local/tmp में पुश करें, फिर शोषण को LD_PRELOAD के अंतर्गत चलाएं। लाइव bring-up लक्ष्य पर tee के बिना चलाएं — tee अपने स्वयं के stdio को बफर करता है और कर्नेल पैनिक पर लॉग का अंतिम भाग खो देता है (शोषण का stdout अनबफर्ड है, इसलिए सीधे फ़ाइल में रीडायरेक्ट करने से हर पंक्ति संरक्षित रहती है):
adb push build/m1q-BP4A.251205.006/bin/preload.so /data/local/tmp/preload.so
adb push build/embed/su_daemon_aarch64_pie /data/local/tmp/su_daemon_aarch64_pie
adb shell "chmod 755 /data/local/tmp/preload.so /data/local/tmp/su_daemon_aarch64_pie"
adb shell "LD_PRELOAD=/data/local/tmp/preload.so \
/data/local/tmp/su_daemon_aarch64_pie \
> /data/local/tmp/output.log 2>&1"
सफलता पर डेमन /data/local/tmp/temp_su.sock पर सुनता है और su /apex/com.android.virt/bin के अंतर्गत स्थापित होता है।
exploit/
Makefile
assets/ # wallpaper.webp (embedded post-root artifact)
src/
main.c # run_exploit() entry point (shared)
preload.c # LD_PRELOAD constructor, su/wallpaper install
util.c # addr translation, page prep, configfs helpers
pipe.c # pipe-based physical read/write
root.c # cred patching / task walk
slide.c # KASLR slide (tracefs + boot_id routes)
fops.c # pselect corruption + fops manipulation
faketables.c # stage-3 fake page-table builders (3-level)
stage3.c # pgd-swap bridge child (no-op unless configured)
stage3_loop.S, stage3_poll.S # bridge blob + enter trampoline
su_daemon.c # root daemon (compiled as separate PIE)
su_blob.S, wallpaper_blob.S # embedded binaries
offset.h # pulls per-target target.h via -DTARGET_CONFIG_H
kernelsnitch/ # mm_struct futex-hash leak library
targets/<codename>-<build>/ # per-device target.h + optional overrides
poc/poc.c # standalone POC (separate from the exploit)
लक्ष्य Makefile pick_src तंत्र के माध्यम से साझा स्रोतों को ओवरराइड करते हैं: यदि src/targets/<PROJECT>/<file>.c मौजूद है तो साझा src/<file>.c के बजाय इसका उपयोग किया जाता है; अन्यथा साझा संस्करण का उपयोग किया जाता है।
-EDEADLK (errno 35) के साथ विफल होने पर निर्भर करता है। चक्र की अनुपस्थिति शून्य कर्नेल प्रभाव के साथ success=1 के रूप में दिखाई देती है।PSELECT_WAITER_WORD_SHIFT 0 होना चाहिए (ZF1 स्टैक गहराई ELF से सत्यापित)। अन्य लक्ष्य अभी भी डिफ़ॉल्ट रूप से 1 का उपयोग करते हैं — उन पर भरोसा करने से पहले प्रति डिवाइस सत्यापित करें।p0_data_alias() DIRECT_MAP_BASE का उपयोग करता है (लीनियर मैप), जो ZF1 पर P0_PAGE_OFFSET से भिन्न होता है। डीरेफरेंस किए गए कर्नेल ऑब्जेक्ट्स के लिए डेटा एलियास को लीनियर मैप का उपयोग करना चाहिए।pr_error() घातक है (exit(-1)), चेतावनी/जानकारी मैक्रोज़ के विपरीत।SLIDE_LOGGERS_0_1 का उपयोग करता है, SLIDE_NFULNL_LOGGER का नहीं; यह वर्ड एक गैर-रैंडमाइज़्ड लीनियर-मैप एलियास है, इसलिए boot_id मार्ग स्लाइड-स्वतंत्र है (इसे केवल slide=0 पर उपयोग करें — पहले tracefs लीक चलाएं)।यह Android डिवाइसों के लिए शोषण कोड है और सुरक्षा अनुसंधान, अधिकृत भेद्यता परीक्षण, और उस हार्डवेयर पर रक्षा कार्य के लिए है जिसके आप स्वामी हैं या जिसके परीक्षण की आपके पास स्पष्ट अनुमति है। उन डिवाइसों पर दुरुपयोग जिनके आप स्वामी नहीं हैं, अवैध है। लेखक ब्रिक हुए डिवाइसों, ब्रिक हुए कर्नेल, या समाप्त वारंटी के लिए ज़िम्मेदार नहीं है।
preload.c एम्बेडेड su डेमन (tmpfs-माउंटेड /apex/com.android.virt/bin में, साथ ही adbd-नेमस्पेस और लोकल वेरिएंट) स्थापित करता है और वॉलपेपर बदल देता है।| चर | डिफ़ॉल्ट | उद्देश्य |
|---|
PSELECT_ROUTE_SHIFT | compile-time | मुख्य मार्ग के लिए A/B fd_set वर्ड शिफ्ट (m1q) |
SLIDE_SHIFT | compile-time | स्लाइड मार्ग के लिए A/B fd_set वर्ड शिफ्ट |
PSELECT_ROUTE_DELAY_USEC | 50000 | sched_setattr से पहले कंज़्यूमर विलंब (> 0 होना चाहिए) |
SLIDE_CONSUME_USEC, SLIDE_ENTER_DELAY_USEC, SLIDE_CONSUMER_CORE | — | स्लाइड मार्ग टाइमिंग/पिनिंग |
SKIP_SLIDE | 0 | डायरेक्ट-मैप फॉलबैक का उपयोग करें (slide = 0) |
SLIDE_ONLY | 0 | केवल KASLR स्लाइड चलाएं और बाहर निकलें |
SLIDE_P0_OFFSET, SLIDE_BOOTID_OFF | — | स्लाइड p0-एलियास / boot_id ऑफसेट ओवरराइड करें |
KSNITCH_COLLISIONS | 4 | KernelSnitch टकराव संख्या |
STAGE3 | 0 | pgd-swap ब्रिज चाइल्ड चरण सक्षम करें (m1q) |
STAGE3_DRYRUN | 0 | टेबल स्टेज/सत्यापित करें फिर स्वैप से पहले रद्द करें |
PAGE_RECLAIM_SENDS, PSELECT_SIMPLE_LAYOUT | — | स्प्रे/fd-set लेआउट ट्वीक |
TMP_PAGE_* / TMP_UNAME_* | — | tmp_page प्रयोग मार्ग (m1q) |