2 पॉइंट द्वारा GN⁺ 4 시간 전 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • GhostLock (CVE-2026-43499) Linux 2.6.39 में पेश की गई और 7.1 में ठीक की गई एक kernel vulnerability है, जिसे बिना विशेषाधिकार वाला local attacker सिर्फ सामान्य threading system calls के ज़रिए stack UAF ट्रिगर करके root privilege escalation और container escape के लिए इस्तेमाल कर सकता है
  • Requeue-PI proxy path में remove_waiter() असली waiting task की जगह current के pi_blocked_on को साफ़ कर देता है, जिससे user space में लौट चुके task में मुक्त किए गए stack frame की ओर इशारा करने वाला pointer बचा रह जाता है
  • तीन futex और तीन threads से PI dependency cycle बनाकर -EDEADLK rollback ट्रिगर किया जाता है, और PR_SET_MM_MAP के controllable stack buffer में नकली rt_mutex_waiter बनाकर constrained pointer write हासिल की जाती है
  • exploit prefetch से KASLR और physmap base address ढूँढता है, फिर CPU entry area (CEA) में नकली structures और ROP stack रखकर inet6_protos[IPPROTO_UDP] को overwrite करता है और IPv6 UDP loopback packet से control flow hijack करता है
  • शोधकर्ताओं ने 97% स्थिर privilege escalation·container escape exploit के लिए Google kernelCTF से $92,337 प्राप्त किए, और जिन सभी Linux distributions में patch नहीं है उन्हें नवीनतम LTS में upgrade करना चाहिए

प्रभाव का दायरा और vulnerability का सार

  • GhostLock, VEGA द्वारा खोजी गई Linux kernel vulnerability है, जिसे local non-privileged user बिना किसी अतिरिक्त privilege या user namespace के ट्रिगर कर सकता है
  • इसे 8161239a8bcc के rtmutex rework में पेश किया गया था, और इसका प्रभाव क्षेत्र v2.6.39-rc1 से v7.1-rc1 तक है
  • इसे अप्रैल 2026 में 3bfdc63936dd में ठीक किया गया, और आवश्यक kernel setting सिर्फ CONFIG_FUTEX_PI=y है
  • attacker निम्नलिखित प्रक्रिया से privilege escalate कर सकता है
    • सिर्फ सामान्य threading system calls से kernel stack memory की ओर इशारा करने वाला dangling kernel pointer हासिल करता है
    • लगभग arbitrary address पर pointer या 8-byte 0 लिख सकने वाला constrained primitive बनाता है
    • function table को hijack करके control flow पर कब्ज़ा करता है और root privilege हासिल करता है
  • patch न किए गए सभी Linux distributions प्रभावित हैं, इसलिए उन्हें नवीनतम LTS version में upgrade करना चाहिए

remove_waiter() गलत task को साफ़ क्यों करता है

  • kernel/locking/rtmutex.c में remove_waiter() मूल रूप से उस path के लिए लिखा गया था जहाँ blocked thread अपनी waiting state खुद साफ़ करता है
  • सामान्य slow path में चल रहा current, waiter का owner task होता है, इसलिए current->pi_blocked_on को साफ़ करना सही होता है
  • Requeue-PI proxy path में rt_mutex_start_proxy_lock() किसी दूसरे sleeping task की ओर से rt_mutex_waiter को queue में डालता है, और error होने पर उसे rollback करता है
    • इस समय current, FUTEX_CMP_REQUEUE_PI कॉल करने वाला requeuer होता है
    • असली waiter, FUTEX_WAIT_REQUEUE_PI में सोया हुआ अलग task होता है
  • जब __rt_mutex_start_proxy_lock() -EDEADLK लौटाता है, तब remove_waiter() waiter को lock से हटाते हुए भी सिर्फ current->pi_blocked_on को NULL बनाता है
  • असली waiter का pi_blocked_on अपनी kernel stack में मौजूद rt_mutex_waiter की ओर इशारा करता रहता है, और waiter के user space में लौटने पर वह stack frame मुक्त माना जाता है
  • इसके बाद जब भी PI chain traversal उस task से होकर गुजरती है, तो मुक्त किए गए stack object को dereference किया जाता है
  • lockdep सिर्फ यह जाँचता है कि कौन-सा pi_lock पकड़ा गया है, यह नहीं कि वह किसका lock है, इसलिए वह इस त्रुटि को पकड़ नहीं पाता

-EDEADLK rollback बनाने वाली तीन-futex cycle

  • error path तक पहुँचने के लिए तीन futex और तीन threads से PI dependency cycle बनाई जाती है
    • f_pi_chain: PI futex जिसे waiter पहले lock करता है
    • f_pi_target: PI futex जिसे owner पहले lock करता है और जो requeue target बनता है
    • f_wait: सामान्य futex जिस पर waiter FUTEX_WAIT_REQUEUE_PI से wait करता है
  • trigger sequence इस प्रकार है
    1. waiter f_pi_chain को lock करने के बाद FUTEX_WAIT_REQUEUE_PI(f_wait -> f_pi_target) में block होता है, और rt_mutex_waiter उसकी kernel stack पर रखा जाता है
    2. owner f_pi_target को lock करने के बाद waiter द्वारा पकड़े गए f_pi_chain पर block हो जाता है
    3. main thread FUTEX_CMP_REQUEUE_PI(f_wait -> f_pi_target) कॉल करता है
  • जब proxy requeue waiter को f_pi_target से जोड़ने की कोशिश करता है, तो waiter → f_pi_target → owner → f_pi_chain → waiter cycle बंद हो जाती है
  • PI chain traversal -EDEADLK लौटाती है और गलत rollback चलाती है, जिससे waiter dangling pi_blocked_on के साथ जाग जाता है
  • महत्वपूर्ण शर्त यह है कि requeuer तब rollback करे जब waiter अभी भी stack object पकड़े हुए हो; cycle पूरी होने के बाद प्रक्रिया अपने-आप आगे बढ़ती है
  • waiter के user space में लौटने के बाद समय का दबाव नहीं रहता, और बाद में कभी भी sched_setattr() से chain traversal ट्रिगर की जा सकती है
  • setup में तीन threads लगते हैं, लेकिन UAF race स्वयं एक ही CPU core पर भी ट्रिगर की जा सकती है

stack UAF से मिलने वाला प्रारंभिक primitive

  • dangling pointer पहले के FUTEX_WAIT_REQUEUE_PI frame में मौजूद rt_mutex_waiter की ओर इशारा करता है
  • अगर उसी task की उसी stack depth पर controllable bytes फिर से रख दिए जाएँ, तो kernel उसे नकली rt_mutex_waiter की तरह dereference कर सकता है
  • नकली structure को कैसे रखा जाता है, इसके आधार पर एक ही access से दो मुख्य primitives मिलते हैं
    • constraints के साथ लगभग arbitrary address पर pointer लिखा जा सकता है
    • constraints के साथ लगभग arbitrary address पर 8-byte 0 लिखा जा सकता है
  • write से पहले कई pointer dereferences और integrity checks किए जाते हैं, लेकिन शर्तें पूरी होने पर write के बाद भी kernel crash हुए बिना सामान्य रूप से लौट आता है
  • exploit पूरा करने के लिए stack frame reuse, नकली waiter की structural checks पास करना, और write constraints से मेल खाने वाले target चुनना—ये सब आवश्यक हैं

PR_SET_MM_MAP से मुक्त किए गए stack frame का पुन: उपयोग

  • waiter, futex system call से लौटते ही तुरंत prctl(PR_SET_MM, PR_SET_MM_MAP, ...) को कॉल करता है
  • prctl_set_mm_map() उपयोगकर्ता द्वारा दिए गए auxv को fixed-size stack buffer unsigned long user_auxv[AT_VECTOR_SIZE] में कॉपी करता है
  • यह buffer मुक्त किए गए waiter जैसी stack depth पर रखा जाता है, इसलिए बड़ा और aligned controllable qword block पिछले rt_mutex_waiter के ऊपर overlap हो जाता है
  • auxv का overlaid क्षेत्र इस तरह बनाया जाता है
    • tree: इसे एक rb node बनाया जाता है ताकि delete करते समय चुना गया child pointer W0_BASE, tree root तक ऊपर आ जाए
    • task: chain traversal की dereference को सुरक्षित रूप से पार कराने के लिए &init_task पर सेट किया जाता है
    • lock: write target को match कराने के लिए &inet6_protos[IPPROTO_UDP] - 8 पर सेट किया जाता है
    • wake_state: 0 पर सेट किया जाता है
  • auxv को memfd में रखकर कॉपी को page boundary पार कराने लायक arrange किया जाता है, फिर sibling thread prctl के चलने के दौरान पीछे वाले page पर fallocate(PUNCH_HOLE) race लगाकर copy_from_user का समय बढ़ाती है
  • दूसरे CPU पर consumer thread, fake waiter के stack पर बने रहने के दौरान waiter पर sched_setattr() कॉल करके PI chain को traverse करती है
  • clone, setsockopt, pselect, keyctl जैसी अन्य system calls, जो बड़े controllable stack local variables का उपयोग करती हैं, वही भूमिका निभा सकती हैं
  • prctl को इसलिए चुना गया क्योंकि इसका buffer बड़ा और aligned है, और इसके लिए namespace की जरूरत नहीं होती; अतिरिक्त candidates public PoC code में शामिल हैं

rb-tree deletion से constrained pointer write बनाना

  • fake waiter को नियंत्रित कर लेने पर भी तुरंत full arbitrary write नहीं मिलती, और chain traversal यह path चलाती है
    • task->pi_blocked_on से fake waiter को ढूंढा जाता है
    • fake waiter->lock से fake rt_mutex_base को ढूंढा जाता है
    • rt_mutex_dequeue(lock, waiter) lock->waiters से rb-tree deletion करता है
  • उस गुण का उपयोग किया जाता है जिसमें केवल एक child वाले root node को delete करने पर वही child root slot में लिख दिया जाता है
  • lock को target - 8 पर सेट करने से आसपास के data को इस rt_mutex_base field layout की तरह interpret किया जाता है
    • target - 8: wait_lock, जिसे unlocked state के रूप में पढ़ा जाना चाहिए
    • target: waiters.rb_root.rb_node, जिसे overwrite किया जाएगा
    • target + 8: waiters.rb_leftmost
    • target + 16: owner
  • नतीजतन जो single write होती है वह *(uint64_t *)target = W0_BASE है
  • target address को मोटे तौर पर ये शर्तें पूरी करनी चाहिए
    • target - 0x08 के निचले 32 bits 0 होने चाहिए
    • target + 0x08 का 64-bit मान 0 होना चाहिए
    • target + 0x10 के owner pointer में lower flags हटाने के बाद मान 0 होना चाहिए
  • अगर आगे वाला qword locked spinlock जैसा दिखे, तो trylock fail हो जाता है और बिना कुछ लिखे बाहर निकल जाता है
  • अगर पीछे वाले मान uncontrolled top waiter या owner की ओर इशारा करें, या unmapped value हों, तो kernel panic हो सकता है
  • W0_BASE को compare, requeueing, priority update, और owner-less wakeup पूरा होने तक valid रहना चाहिए, इसलिए CEA का direct-map alias उपयोग किया जाता है

prefetch leak और CPU entry area

  • KASLR·physmap base address ढूंढना

    • किसी खास address के लिए prefetch का execution time इस बात पर निर्भर करता है कि current page table में वह address mapped है या नहीं
    • unprivileged process यदि kernel address range के execution time को मापे, तो mapping location का अनुमान लगाया जा सकता है; इसका विस्तृत सिद्धांत prefetch paper में संकलित है
    • default Linux kernel image base address की entropy लगभग 9 bits होने के कारण, repeated measurement से KASLR base address को लगभग 100% विश्वसनीयता के साथ recover किया जाता है
    • सिद्धांततः prefetch और उचित KPTI की अनुपस्थिति वाले CPU प्रभावित होते हैं, लेकिन व्यवहार में यह तकनीक मुख्य रूप से KPTI-disabled x86 पर इस्तेमाल होती है
    • kernelCTF image में KPTI बंद है, और KPTI चालू होने पर भी prefetch तथा EntryBleed को मिलाकर trampoline के जरिए kernel image base address recover किया जा सकता है
  • CEA address randomization को bypass करना

    • CPU entry area(CEA) x86 में प्रति-CPU structure है जो entry और exception handling के लिए stack और register context को store करता है
    • unprivileged program जब software exception पैदा करता है, तो वह अपना register context CEA exception stack के pt_regs में लिख सकता है, जिससे लगभग 120 bytes की contiguous controllable memory बनती है
    • Linux 6.2 से पहले CEA virtual address पूरी तरह fixed था, इसलिए इसे fake structures, pointer dereference side effects absorb करने, और ROP stack बनाने के लिए सीधे इस्तेमाल किया जा सकता था
    • Project Zero के Bringing back the stack attack के प्रकाशित होने के बाद Linux 6.2 से CEA virtual address को मजबूती से randomize किया गया
    • हर CPU का CEA virtual address अलग-अलग randomize होता है, लेकिन physical address fixed रहता है, इसलिए physmap base address पता हो तो direct-map alias की गणना की जा सकती है
    • prefetch, candidate boundary normalization, और expected CEA page checking को जोड़कर आसपास के aliases को हटाया जाता है और cea_direct = physmap_base + CPU1_CEA_BASE निकाला जाता है
    • kernelCTF LTS 6.12.80 के 3.5GB boot environment में संबंधित offset 0x11c517000(+0x1f58) है

CEA का fake waiter और बाद के objects के रूप में पुन: उपयोग

  • पहली write से पहले CEA के W0 में self-consistent fake waiter और lock रखे जाते हैं
    • task को &init_task पर सेट किया जाता है
    • prio में valid value डाली जाती है
    • lock के wait_lock को unlocked state जैसा दिखाया जाता है
    • owner को dequeue, requeueing, priority update, और wakeup को सुरक्षित रूप से पार कराने के लिए configure किया जाता है
  • rb-tree write खत्म होने के बाद W0 को अब waiter बने रहने की जरूरत नहीं होती, इसलिए CEA को उस structure से फिर भरा जा सकता है जिसकी overwritten target को जरूरत हो
  • CEA लगभग 120 bytes का छोटा क्षेत्र है, लेकिन calculable fixed kernel address पर data रखा जा सकता है, इसलिए यह प्रभावी है
  • NPerm और kernelsnitch जैसी चीजें अधिक बड़े space में वही भूमिका निभा सकती हैं
  • exploit एक ही CEA क्षेत्र का उपयोग क्रमिक रूप से या एक साथ fake rt_mutex_waiter, fake lock, inet6_protocol, JOP·stack pivot slots, और अंतिम ROP stack के लिए करता है

inet6_protos[IPPROTO_UDP] से control flow hijack

  • सामान्य x86_64 Linux में KASLR base address हासिल करने के बाद, शर्तों से मेल खाने वाली function table या उसे शामिल करने वाले object को overwrite करने वाला छोटा path चुना जा सकता है
  • writable data area में inet6_protos[IPPROTO_UDP] के आसपास का हिस्सा आवश्यक constraints को स्वाभाविक रूप से पूरा करता है
    • inet6_protos[16] == NULL नकली wait_lock की unlocked state बन जाता है
    • inet6_protos[17] == &udpv6_protocol वास्तविक overwrite target है
    • inet6_protos[18] == NULL नकली rb_leftmost बन जाता है
    • inet6_protos[19] == NULL नकली owner बन जाता है
  • write पूरा होने पर inet6_protos[IPPROTO_UDP] CEA page के अंदर मौजूद नकली inet6_protocol को point करता है
  • CEA को फिर से spray करके structure को इस तरह तैयार किया जाता है
    • handler: इसे पहले pivot gadget के रूप में सेट किया जाता है
    • err_handler: उपयोग नहीं किया जाता
    • flags: INET6_PROTO_NOPOLICY | INET6_PROTO_FINAL पर सेट किया जाता है
  • ::1 पर connect करने के बाद डेटा लिखने वाला IPv6 UDP loopback packet भेजने पर kernel नकली handler को call करता है, जिससे program counter को नियंत्रित किया जा सकता है

छोटा pivot और DirtyMode privilege escalation

  • Google kernelCTF के lts-6.12.80 target पर उपयुक्त single stack pivot gadget नहीं मिला, इसलिए अतिरिक्त load/call के जरिए CEA address को rbp में डालने के बाद mov rsp, rbp; pop rbp; ret से pivot किया गया
  • ret2usr या /proc/%P/fd/x का full overwrite लगभग 10 gadget qword मांगता है, जो सीमित CEA space की तुलना में बहुत बड़ा है
  • अंतिम चरण में एक ही write से privilege bits बदलकर बाकी प्रक्रिया user space में पूरी करने के लिए DirtyMode का उपयोग किया जाता है
  • write target kernel data का coredump_sysctls[1].mode है, यानी core_pattern sysctl का access mode
  • क्योंकि यह kernel image के साथ वही KASLR slide साझा करता है, इसका address निकाला जा सकता है, और write bit वाला दूसरा सबसे कम significant bit सेट होना पर्याप्त है
  • छोटे pop reg; mov [reg], reg; ret chain से mode value बदली जाती है और msleep से hijack किए गए thread को सुरक्षित रूप से रोक दिया जाता है
  • जब /proc/sys/kernel/core_pattern सभी users के लिए writable हो जाता है, तो unprivileged process |/proc/%P/fd/666 %P लिख सकता है और helper को crash कर सकता है, जिससे kernel attacker की binary को root privilege के साथ execute कर देता है
  • शुरुआती rb-tree write batch constraints के कारण सीधे coredump_sysctls[1].mode तक नहीं पहुंच सकती, इसलिए mode change छोटा ROP चरण में किया जाता है

पूरा exploit flow और परिणाम

  • हमला इस क्रम में आगे बढ़ता है
    1. prefetch से kernel image slide और physmap base address leak किया जाता है
    2. GhostLock के जरिए waiter के pi_blocked_on में dangling rt_mutex_waiter छोड़ा जाता है
    3. PR_SET_MM_MAP से उसी kernel stack frame को reuse करके नकली waiter बनाया जाता है
    4. rtmutex rb-tree deletion का उपयोग कर inet6_protos[IPPROTO_UDP] में CEA pointer लिखा जाता है
    5. CEA में नकली inet6_protocol, pivot slot, और ROP stack रखा जाता है
    6. IPv6 UDP loopback packet से overwritten handler को call किया जाता है
    7. DirtyMode से core_pattern के mode bits बदले जाते हैं और user space में privilege escalation पूरी की जाती है
  • kernelCTF remote environment में CEA और DirtyMode के संयोजन वाला path लगभग 5 सेकंड में flag हासिल कर लेता है
  • पूरा exploit CyberMeowfia project में सार्वजनिक है
  • Android में stack frame reuse और ASLR·CFI bypass का तरीका अलग है, जिसे अलग follow-up लेख में कवर किया जाएगा

वैकल्पिक path और mitigation

  • बड़ा ROP space

    • NPerm आधारित memory control flow hijack के बाद बड़े नकली stack के रूप में इस्तेमाल की जा सकती है
    • Lukas Maar की heap-KASLR leak जैसी भारी path भी संभव है, लेकिन steps बढ़ने से execution time लंबा हो जाता है
    • kernelCTF में सबसे छोटा और सबसे reliable chain फायदेमंद होता है, इसलिए CEA और DirtyMode का संयोजन इस्तेमाल किया गया
  • kernel patch

    • अंतिम patch में current की जगह waiter->task के आधार पर pi_lock लिया जाता है और pi_blocked_on साफ किया जाता है
    • remove_waiter() waiter_task = waiter->task को store करने के बाद इस क्रम में काम करता है
      1. waiter_task->pi_lock को lock करता है
      2. waiter को rtmutex queue से हटाता है
      3. waiter_task->pi_blocked_on = NULL पर सेट करता है
      4. बाद के rt_mutex_adjust_prio_chain() में भी current की जगह waiter_task पास करता है
    • शोधकर्ताओं का v1 से पहले भेजा गया अलग fix caller को owner task स्पष्ट रूप से pass करने के लिए बनाता है
      • खुद block होने वाले path में current pass किया जाता है
      • proxy rollback में proxy target task pass किया जाता है
      • केवल तब साफ किया जाता है जब pi_blocked_on अभी भी उसी waiter को point कर रहा हो, और इसे task के pi_lock से protect किया जाता है
  • RANDOMIZE_KSTACK_OFFSET

    • exploit इस बात पर निर्भर करता है कि freed waiter frame और बाद वाला user_auxv frame deterministic तरीके से overlap हों
    • RANDOMIZE_KSTACK_OFFSET चालू होने पर stack offset बदल जाता है, जिससे यह चरण लगभग 1/32 संभावना वाले 5-bit guess में बदल जाता है
    • जमा किए गए दो सामान्य targets में यह setting default रूप से बंद थी, जबकि mitigated target में यह चालू थी, इसलिए वहां यह exploit path इस्तेमाल नहीं किया गया
  • STATIC_USERMODE_HELPER

    • STATIC_USERMODE_HELPER इस खास DirtyMode path को रोकता है
    • हालांकि access permission ctl_table::mode से नियंत्रित होती है और table predictable writable kernel data में होती है, इसलिए यही तरीका दूसरे /proc/sys settings पर भी सामान्यीकृत किया जा सकता है

disclosure timeline

  • 18 अप्रैल 2026: vulnerability और draft patch को security@kernel.org पर भेजा गया
  • 20 अप्रैल 2026: एक दूसरे patch से vulnerability fix हुई
  • 4 मई 2026: fix v1 backport किया गया
  • 30 जून 2026: Google ने kernelCTF submission की पुष्टि की
  • 7 जुलाई 2026: तकनीकी विश्लेषण सार्वजनिक किया गया
  • VEGA द्वारा खोजी गई vulnerability पर मानक 90+30 दिन disclosure policy लागू होती है

1 टिप्पणियां

 
GN⁺ 4 시간 전
Hacker News की राय
  • Android 9·13·16 और Firefox 150 से कम के अलग-अलग versions चलाने वाले 3 devices पर टेस्ट किया; 2 devices boot loop में फंस गए और recovery mode में जाना पड़ा, जबकि बाकी 1 device बंद हो गया। Demo supported Pixel devices का wallpaper बदलता है, और test page IonStack पर देखा जा सकता है।
    अपने personal device पर blog या random sites देखते समय main browser से अलग Chromite जैसा Chromium-based browser install करना, flags में JavaScript और अक्सर attack होने वाले hardware-accelerated video decoder को बंद करना, और broken sites के लिए reading mode इस्तेमाल करना ज्यादा सुरक्षित है। या फिर dedicated tablet रखने का विकल्प भी है।

    • अभी सिर्फ Pixel 10 पर test किया गया है, लेकिन दूसरे devices support करने के लिए कुछ PRs आ रहे हैं; इन्हें https://github.com/NebuSec/CyberMeowfia पर देखा जा सकता है।
    • kernel exploit को दूसरे device पर port करके देखा, तो यह हर kernel build में compiler द्वारा stack frame arrange करने के तरीके के प्रति बेहद sensitive था। किसी specific build के लिए सही stamping method और offsets मिल जाने के बाद यह काफी stable चलता है।
    • जोखिम उठाकर Samsung S26 Ultra पर चलाया है; adb install करके verify करने के बाद पूरा result बताऊंगा।
      test page पर जाने पर Firefox tab में output दिखा, जिससे लगा कि proof-of-concept code चल गया, लेकिन इसके बाद phone freeze हो गया और सारे inputs reject करने लगा। सिर्फ restart काम कर रहा था; kernel रुका हुआ लगने की स्थिति में भी यह restart event पर कैसे respond कर पाता है, यह जानना दिलचस्प है। Screen execution result का कुछ हिस्सा दिखाते हुए on रही, फिर screen saver चालू हो गया।
    • अगर इसका इस्तेमाल अभी root न किए जा सकने वाले Android devices को root करने में किया जा सके तो शानदार होगा; जानना चाहूंगा कि ऐसा कैसे संभव है।
    • Firefox vulnerability IonMonkey JIT compiler की type confusion, CVE-2026-10702, लगती है: https://www.sentinelone.com/vulnerability-database/cve-2026-10702/
  • exploit खोजने के साथ-साथ, copyfail के उलट, सबके लिए तुरंत usable zero-day local privilege escalation script publish न करने वाले security researchers को बहुत सराहना।
    Rocky Linux 9 पर कई घंटों तक local privilege escalation (LPE) try किया, लेकिन शुक्र है कि सफल नहीं हुआ। जब तक बहुत ज्यादा time या बहुत ऊंची skill न हो, enterprise distributions पर इसे real attack में इस्तेमाल करना मुश्किल लगता है।

  • सोच रहा हूं कि आम तौर पर जिन phones का bootloader unlock नहीं किया जा सकता, क्या इस vulnerability से उन पर bootloader unlock संभव होगा। अगर संभव हुआ, तो यह Android ecosystem में हुई सबसे अच्छी घटनाओं में से एक हो सकती है।

  • Title में local privilege escalation के लिए LPE डाल देना चाहिए था, ताकि ज्यादातर लोग निश्चिंत होकर weekend पर लौट जाते।

    • इतना निश्चिंत होने वाली बात नहीं है। आम तौर पर local privilege exploit का मतलब normal user privileges से root privileges तक जाना होता है, और normal-privilege apps भी पहले से काफी नुकसान कर सकते हैं, इसलिए लोग अक्सर बहुत चिंता नहीं करते।
      लेकिन यह attack Firefox के isolated browser process जैसे strongly sandboxed process के अंदर भी trigger हो सकता है। Attacker को बस JavaScript vulnerability से isolated sandbox में local code चलाने और फिर इस vulnerability से kernel mode तक पहुंचने वाले two-stage attack को chain करना होगा, इसलिए Firefox और Linux kernel दोनों update करने होंगे।
    • ऊपर वाले comment का attack JavaScript से सीधे root privileges लेने जैसा दिखता है, लेकिन असल में यह दो अलग-अलग exploits को chain करता है।
    • अगर container escape संभव है, तो शायद इसका असर अब भी बहुत लोगों पर पड़ सकता है।
    • Firefox/IonMonkey की type confusion vulnerability भी साथ में मिली है, इसलिए किसी arbitrary website पर जाने भर से device बहुत जल्दी compromise हो सकता है।
    • आजकल लगता है कि ऐसी situations में खर्च करने के लिए जमा किए गए zero-days सैकड़ों में होंगे। SSH से लेकर Node.js तक हर कुछ हफ्तों में नया issue आता है, इसलिए जब तक सभी communications को WireGuard के पीछे न रखा जाए, व्यवहार में सबको remote vulnerability जैसा ही treat करना पड़ेगा।
  • “Google ने kernelCTF reward के तौर पर 92,337 dollars दिए” वाला हिस्सा आते ही ध्यान खिंच गया।

    • impact scope देखते हुए यह amount कम लगता है। सोचता हूं कि क्या companies सिर्फ remote exploits के लिए ही बड़ा पैसा देती हैं।
  • क्या इसका मतलब है कि Android app NDK से native code चलाकर root privileges हासिल कर सकती है, और क्या SELinux defense में मदद करता है?

    • non-flagship phones को kernel समेत updates शायद ही मिलते हैं, इसलिए असल में ऐसा हो पाने की संभावना ज्यादा लगती है।
      पुराने kernels में भी patch backport किया जा सकता है, लेकिन smartphone update changelogs में CVE specify करना दुर्लभ है, इसलिए vulnerability scanner ही व्यावहारिक रूप से confirm करने का अकेला तरीका है। Play Store या बाहर से ली गई app compromise हो गई हो, तो वह तुरंत root privileges पा सकती है; इसलिए install करते समय trust और audit check करने का principle अब भी important है।
      आगे चलकर संभव है कि यह check Google Play Integrity के सभी levels में जोड़ दिया जाए और unpatched phones पर कई apps install न हो पाएं। Browser में, जहां arbitrary sites और ads से बचना मुश्किल है, sandbox escape app isolation तक को bypass कर देता है, इसलिए यह और गंभीर है; iOS के JailbreakMe जैसा।
    • अगर kernel खुद compromise हो जाए, तो SELinux defend नहीं कर सकता। Android sandbox या Docker जैसी container technologies भी इस exploit को नहीं रोकतीं, और practical isolation का साधन सिर्फ full virtualization है। अगर KVM इस्तेमाल कर रहे हैं, तो यह मानना होगा कि पिछले हफ्ते disclosed CVE-2026-53359 का patch हर जगह deploy हो चुका है।
      पिछले 15 साल में आए Linux पर native code चला सकने वाली कोई भी app, device पर kernel update आने तक root privileges हासिल कर सकती है।
  • यह चौंकाने वाला है कि GhostLock Linux 2.6.39 में आया था और Linux 7.1 में जाकर ही fix हुआ।

  • लगता है मैंने ये comments एक दिन पहले ही पढ़ लिए थे, लेकिन writing time सभी 10 घंटे के अंदर दिख रहे हैं; सोच रहा हूं कि HN का time display गलत है क्या।

    • संभवतः यह HN के re-up system की वजह से हुआ है। इस post को फिर से ऊपर लाने पर पुराने comments के timestamps relative time के तौर पर recalculated हुए; संबंधित जानकारी https://hn.algolia.com/?dateRange=all&page=0&prefix=true&query=by%3Adang%20timestamps%20re-up&sort=byDate&type=comment पर देखी जा सकती है।
      रोज देखी जाने वाली “underwater” list—यानी वे posts जिन्हें बहुत upvotes मिले लेकिन किसी वजह से front page पर नहीं आ पाईं—में यह post सबसे ऊपर थी, इसलिए इसे फिर से expose किया गया। यह अजीब दिखता है, लेकिन अभी इससे कम confusing alternative नहीं मिला है।
    • कभी-कभी similar articles को एक में मिलाते समय comments भी merge कर दिए जाते हैं।