
Linux कर्नेल UAF विश्लेषण CVE-2026-64560 के लिए, जिसमें रेस-ट्रिगरिंग PoC, पैच समीक्षा, प्रभावित LTS/Android संस्करण मैट्रिक्स, और पैच किए गए डिवाइसों के लिए स्व-जांच शामिल है।
Reproducer / PoC (ट्रिगर सत्यापन प्रकार): Linux और Android (NDK) यह रिपॉज़िटरी केवल अपने स्वयं के परीक्षण उपकरणों पर पैच स्थिति सत्यापित करने और शोध/सीखने के लिए है; इसमें कोई विशेषाधिकार वृद्धि/शोषण प्रिमिटिव शामिल नहीं है।
| फ़ील्ड | विवरण |
|---|---|
| CVE ID | CVE-2026-64560 |
| शीर्षक | posix-cpu-timers: Prevent UAF caused by non-leader exec() race |
| प्रकार | Use-After-Free (CWE-416), प्रतिस्पर्धा स्थिति |
| CNA | kernel.org (Linux CNA) |
| CVSS v3.1 | 7.8 High — CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| CVSS v4.0 (SUSE) | 8.5 High — CVSS:4.0/AV:L/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N |
| EPSS | ~0.12% (दूसरा परसेंटाइल, 2026-08 तक) |
| CISA KEV | सूचीबद्ध नहीं |
| सार्वजनिक तिथि | 2026-07-29 |
| फिक्स कमिट (मेनलाइन) | 920f893f735e92ba3a1cd9256899a186b161928d |
| समस्या पेश करने वाला कमिट (Fixes:) | 55e8c8eb2c7b (v5.7, 2020) — "posix-cpu-timers: Store a reference to a pid not a task" |
| फिक्स करने वाला | Thomas Gleixner <[email protected]> |
| रिपोर्ट करने वाले | Wongi Lee <[email protected]>, Jungwoo Lee <[email protected]> |
| प्रभावित फ़ाइलें | kernel/exit.c, kernel/signal.c, kernel/time/posix-cpu-timers.c |
यह भेद्यता v5.7 (2020-05) में पेश की गई थी, और फिक्स को सभी स्थिर शाखाओं में बैकपोर्ट किया गया है:
| ब्रांच | प्रभावित | फिक्स संस्करण (≥) | स्थिर फिक्स कमिट |
|---|---|---|---|
| 5.10 LTS | 5.7 ~ 5.10.261 | 5.10.262 | 67aa823e3e8c |
| 5.15 LTS | ~ 5.15.212 | 5.15.213 | d8bcb28abad8 |
| 6.1 LTS | ~ 6.1.179 | 6.1.180 | cc35ddbc4973 |
| 6.6 LTS | ~ 6.6.146 | 6.6.147 | 12a891c773ae |
| 6.12 LTS | ~ 6.12.99 | 6.12.100 | e74443f5db00 |
| 6.18 | ~ 6.18.40 | 6.18.41 | 6a7ecc25abe6 |
| 7.1 | ~ 7.1.4 | 7.1.5 | ad1cafa1bdaa |
| mainline | < 7.2-rc3 | 7.2-rc3 | 920f893f735e |
Android GKI कर्नेल 5.10 / 5.15 / 6.1 / 6.6 / 6.12 LTS पर आधारित हैं, और सभी प्रभावित सीमा में आते हैं। चूँकि मेनलाइन फिक्स कमिट 2026-07-29 को जारी किया गया था, 2026-08-01 या उससे पहले के SPL (सुरक्षा पैच स्तर) वाले Android डिवाइसों में अधिकतर यह फिक्स शामिल नहीं है। डिवाइस पर adb shell cat /proc/version और getprop ro.build.version.security_patch के द्वारा कर्नेल संस्करण और SPL की पुष्टि करें।
POSIX CPU टाइमर (timer_create(CLOCK_PROCESS_CPUTIME_ID, ...) / timer_create(CLOCK_THREAD_CPUTIME_ID, ...)) कर्नेल में kernel/time/posix-cpu-timers.c द्वारा प्रबंधित किए जाते हैं। प्रत्येक k_itimer अपने it.cpu.pid के माध्यम से लक्ष्य कार्य (task) को याद रखता है; टाइमर संचालन के लिए timerqueue की सुरक्षा हेतु lock_task_sighand(p, &flags) से उस task का sighand->siglock प्राप्त करना आवश्यक है।
2020 के कमिट 55e8c8eb2c7b ने टाइमर में कैश्ड task पॉइंटर को pid संदर्भ से बदल दिया (2010 के workaround e0a70217107e द्वारा पेश की गई समस्या को ठीक करने के लिए), और प्रत्येक संचालन से पहले pid_task(pid, type) लुकअप किया गया। इस परिवर्तन ने इस CVE के लिए रेस विंडो छोड़ दी।
जब execve() गैर-लीडर थ्रेड द्वारा शुरू किया जाता है, तो de_thread() → switch_leader() TGID को पुराने लीडर से नए लीडर में स्थानांतरित करता है, और पुराना लीडर release_task() → __exit_signal() से गुजरता है, जिसमें old_leader->sighand = NULL सेट किया जाता है और unhash_task(old_leader) किया जाता है।
इसी समय, दूसरे CPU पर निष्पादित sys_timer_delete() → posix_cpu_timer_del():
sys_timer_delete() exec()
posix_cpu_timer_del()
// 观察到旧 leader
p = pid_task(pid, pid_type); de_thread()
switch_leader();
release_task(old_leader)
__exit_signal(old_leader)
sighand = lock(old_leader, sighand);
posix_cpu_timers*_exit();
sighand = lock_task_sighand(p) unhash_task(old_leader);
sh = lock(p, sighand) old_leader->sighand = NULL;
unlock(sighand);
(p->sighand == NULL)
unlock(sh)
return NULL;
// 直接返回,没有摘链!
if (!sighand)
return 0;
free_posix_timer(); // ← k_itimer 被释放
posix_cpu_timer_del() द्वारा प्राप्त p पुराना लीडर है, और इस समय p->sighand == NULL है; फ़ंक्शन मानता है कि "कार्य बाहर निकल रहा है, exit पथ लिंक हटाने का ध्यान रखेगा", इसलिए कुछ भी किए बिना सफलता लौटाता है। उसके बाद free_posix_timer() k_itimer को मुक्त कर देता है।
मुख्य बिंदु: exec() और exit() अलग हैं — exec() में TGID अपरिवर्तित रहता है, और प्रोसेस-स्तर (p->signal->cpu_timers) पर जुड़े armed टाइमर विरासत में मिलते हैं और अभी भी कतार में बने रहते हैं। इस प्रकार:
run_posix_cpu_timers() (tick में timerqueue ट्रैवर्सल) मुक्त वस्तु के timerqueue_node तक पहुँचता है → UAF पढ़ना/लिखना;इसी प्रकार की समस्याएँ निम्न में भी मौजूद हैं:
posix_cpu_timer_set(): सामान्य टाइमर केवल अस्थायी रूप से -ESRCH लौटाता है; लेकिन कर्नेल आंतरिक do_cpu_nanosleep() स्टैक पर आवंटित k_itimer का उपयोग करता है, यह वही UAF है।posix_cpu_timer_rearm(): चुपचाप rearm विफल हो जाता है, टाइमर फिर कभी समाप्त नहीं होता (कार्यात्मक बग)।Frederic Weisbecker ने बताया: __exit_signal() में tsk->sighand = NULL एक साधारण स्टोर है; ARM64 जैसे कमजोर-क्रम आर्किटेक्चर पर, जब posix_cpu_timer_del() sighand == NULL देखता है, तो यह गारंटी नहीं है कि वह posix_cpu_timers*_exit() से पहले के अनलिंक लेखन को देखेगा, जिससे WARN_ON_ONCE(timer_queued(tmr)) गलत तरीके से ट्रिगर हो सकता है।
__exit_signal() में smp_store_release(&tsk->sighand, NULL) का उपयोग करें;lock_task_sighand() के !sighand पथ में smp_acquire__after_ctrl_dep() जोड़ें;timer_lock_sighand() जोड़ें: task खोजें + sighand लॉक करें; यदि sighand == NULL है तो वापस लौटने के बजाय खोज फिर से करें — exec परिदृश्य में नया लीडर मिलेगा, exit परिदृश्य में खोज विफल होने पर ही छोड़ें;_del / _set / _rearm) समान रूप से इस हेल्पर का उपयोग करें।पूर्ण diff के लिए patches/920f893f735e.patch देखें।
poc/ में एक प्रतिस्पर्धा ट्रिगर प्रदान किया गया है: दो थ्रेड उच्च तीव्रता पर लूप चलाते हैं
timer_create(CLOCK_PROCESS_CPUTIME_ID) → arm (बहुत छोटा प्रारंभिक समाप्ति समय) → व्यस्त-प्रतीक्षा ट्रिगर → timer_delete();fork() → चाइल्ड प्रोसेस में एक गैर-लीडर थ्रेड बनाएं, और वह थ्रेड execve() को कॉल करे (गैर-लीडर exec इस भेद्यता के लिए आवश्यक शर्त है), माता-पिता तुरंत waitpid() से रीसाइकिल करता है।