- Linux 6.9 से, laptop suspend के दौरान drive को lock करने वाला tool चुपचाप fail हो रहा था, जिससे LUKS full-disk encryption key memory में बची रह गई
- वजह मई 2024 में Linux 6.9 में आया block device access refactoring और encryption code के बीच अप्रत्याशित interaction था; प्रस्तावित fix एक single-line patch है
- पूर्ण shutdown में समस्या सामने नहीं आई, लेकिन suspend-to-RAM में key बची रही, जिससे powered-on laptop हासिल करने वाला attacker RAM से key निकाल सकने की स्थिति में आ गया
- खोज Debian
cryptsetup-suspendके NixOS port को साफ करते समय/proc/keysentries देखने से शुरू हुई, और QEMU memory dump से पुष्टि हुई कि मिट जानी चाहिए थी ऐसी volume key बची हुई थी - NixOS integration test और cryptsetup warning patch प्रस्तावित किए गए हैं; suspend से ठीक पहले key deletion जैसे security features सामान्य दिखने पर भी actual memory verification के बिना उनकी विफलता छूटना आसान है
Linux 6.9 के बाद suspend के दौरान LUKS key बची रहने की समस्या
- Linux 6.9, यानी मई 2024 से, laptop suspend के समय drive को lock करने वाला tool चुपचाप fail हो रहा था
- LUKS full-disk encryption laptop खोने, जब्त होने या चोरी होने पर data बचाने के लिए इस्तेमाल होता है, लेकिन इस मामले में suspend के दौरान encryption key memory में बची रह गई
- पूर्ण shutdown में यह अब भी काम कर रहा था, लेकिन laptop को पूरी तरह बंद करने के बजाय अक्सर suspend-to-RAM में छोड़ने की वजह से इसका प्रभाव बड़ा हो जाता है
- अगर कोई व्यक्ति powered-on हालत में laptop हासिल कर ले, तो memory में बची key expose हो सकने की स्थिति थी
- Windows पर इसी उद्देश्य के software के रूप में VeraCrypt का उल्लेख हुआ था, लेकिन बाद की comments में “canonical software” का अर्थ सबसे ज़्यादा इस्तेमाल होने वाला software नहीं, बल्कि IT security क्षेत्र में representative recommendation बताया गया
वजह और single-line patch
- वजह Linux kernel refactoring commit md: port block device access to file था
- बदलाव अपने आप में समझदारी भरा और उपयोगी refactoring था, लेकिन इससे encryption code के साथ long-distance interaction पैदा हुआ
- प्रस्तावित fix single-line patch है
- patch author ने कहा कि formal verification के बिना यह नहीं कहा जा सकता कि यह patch सही है और कोई दूसरा long-distance interaction नहीं है
- recurrence रोकने के लिए follow-up work भी साथ आया
- NixOS automated test: भविष्य में regression detect करने के लिए integration test
- cryptsetup merge request: चुपचाप fail होने के बजाय warning output करने वाला patch
खोज की प्रक्रिया
- शुरुआत Debian
cryptsetup-suspendके NixOS port को साफ करने के काम से हुई - Debian original और NixOS port, दोनों में एक असुविधाजनक लेकिन harmful नहीं race condition थी, जिससे laptop कभी-कभी sleep नहीं कर पाता था
- इसे हल करने के लिए Pali Rohár के unmerged kernel patch dm-crypt suspend/hibernation key deletion patch को फिर से revive करने की कोशिश की गई
- उसी दौरान cryptsetup और kernel source code देखते हुए यह पुष्टि हुई कि documentation के अनुसार keyring calling thread से जुड़ता है और thread exit पर remove हो जाता है
- लेकिन पहले से अनजान
/proc/keysमें entries दिखीं, जिससे शक बढ़ा - आखिर में QEMU virtual machine चलाकर memory dump किया गया, और पुष्टि हुई कि मिट जानी चाहिए थी ऐसी LUKS volume key जस की तस बची हुई थी
NixOS secure suspend-to-RAM project
- अलग से जारी
secure-suspendproject NixOS में experimental secure suspend-to-RAM देता है - सामान्य full-disk encryption में laptop suspend state में होने पर key memory में बची रहती है, जिससे cold boot attack या RAM leakage तरीकों के प्रति vulnerability हो सकती है
- यह project Pali Rohár के पुराने kernel patch को revive कर suspend के समय LUKS encryption key मिटाने का तरीका अपनाता है
- यह Debian
cryptsetup-suspendसे प्रेरित है, लेकिन kernel patch का उपयोग करके laptop के कभी-कभी sleep न कर पाने वाली race condition से बचता है और अतिरिक्त safeguards जोड़ता है - encrypted root filesystem को पूरी तरह support करता है, और integration tests भी देता है
- kernel patch और user-space tools को दूसरे Linux distributions के लिए भी adapt किया जा सकता है
- project secure-suspend के रूप में public है
suspend security verification मुश्किल क्यों है
- suspend के बाद screen lock दिखने का मतलब यह नहीं कि storage device सच में lock हो गया है
- suspend से जागने के तुरंत बाद अगर disk access संभव है, तो समझा जा सकता है कि storage device शुरू से ही lock नहीं हुआ था
- उदाहरण के लिए lock screen के पीछे लगातार चलने वाली script से disk access check किया जा सकता है
- suspend के बाद अगर SSH public key से पहले encrypted storage unlock किए बिना connect किया जा सकता है, तो यह confirm करना आसान है कि storage device lock नहीं हुआ
- कुछ comments में यह भी कहा गया कि Ubuntu या Debian default configuration में ऐसी protection देने की कोशिश ही नहीं थी
- storage device को lock करने की कोशिश वास्तव में सही ढंग से काम कर रही थी या नहीं, इसे अलग से verify करना होगा
- log timestamps suspend से पहले बने हो सकते हैं, लेकिन wake के बाद लिखे गए हो सकते हैं
- इसके उलट, wake के तुरंत बाद system time adjust होने से पहले बने logs suspend time जैसे दिख सकते हैं
- storage device lock suspend से ठीक पहले हुआ या resume के तुरंत बाद, user experience में एक जैसा दिख सकता है, लेकिन security के लिहाज से यह निर्णायक अंतर है
- NixOS integration test virtual machine में system boot करके memory dump करता है, ताकि यह confirm किया जा सके कि suspend के समय key सचमुच मिटाई गई या नहीं
1 टिप्पणियां
Hacker News की राय
यह निश्चित रूप से एक दिलचस्प bug है, लेकिन शीर्षक थोड़ा clickbait जैसा लगता है
मेरी समझ के अनुसार
cryptsetup luksSuspendकोई आधिकारिक रूप से समर्थित फीचर कम और Debian द्वारा बनाया गया extension ज़्यादा है, इसलिए शायद यह regression भी सिर्फ Debian को ही प्रभावित करता थाजो फीचर न तो supported है और न ही व्यापक रूप से tested, उसके लिए kernel को दोष देना चाहिए या नहीं, यह साफ़ नहीं है
फिर भी यह काफ़ी प्रभावशाली है, और अच्छा है कि ऐसा regression दोबारा न आए इसके लिए अब test मौजूद है। OP की NixOSTests वाली राय से भी मैं पूरी तरह सहमत हूँ
हालाँकि सिर्फ शीर्षक पढ़ने पर यह किसी एक distribution की बजाय व्यापक समस्या जैसा लगता है
सही है। जो लोग default setup इस्तेमाल कर रहे हैं, वे प्रभावित नहीं होते, क्योंकि वे शुरू से यह उम्मीद नहीं करेंगे कि suspend के दौरान volume key सुरक्षित रहेगी
Debian का समाधान कई, और शायद ज़्यादातर दूसरे distributions में port किया गया था, और संभव है कि काफ़ी लोग अपना निजी port भी maintain कर रहे हों
thread-keyring(7)man page यह वादा करती है कि “thread keyring उस thread के समाप्त होते ही नष्ट हो जाती है जो उसे reference करता है”cryptsetup project user space से kernel space में keys भेजने के mechanism में इसी गुण पर निर्भर था, और kernel 6.9 ने एक regression के ज़रिए इसी गुण को तोड़ दिया
मैंने इसे पहले Arch और openSUSE पर भी कभी-कभी इस्तेमाल किया है, और यह स्पष्ट रूप से non-Debian distributions में भी मौजूद है
शायद आप system suspend के साथ automatic integration की बात सोच रहे हैं, लेकिन वह मुख्य मुद्दा नहीं है।
luksSuspendके बारे में दस्तावेज़ में लिखा है कि यह system memory से keys हटा देता है, और Linux 6.9 के उसी refactoring patch की वजह से यह व्यवहार बंद हो गयाहालाँकि व्यवहारिक रूप से इसे cryptsetup की तरफ़ का bug भी माना जा सकता है। वजह यह है कि यह kernel keyring key के बहुत specific lifetime behavior पर निर्भर था, और यह तर्क दिया जा सकता है कि user space से इसे ज़्यादा स्पष्ट रूप से मिटाया जाना चाहिए था
[1]: https://gitlab.com/cryptsetup/cryptsetup/-/commit/3cea5dcc7b...
[2]: https://gitlab.com/cryptsetup/cryptsetup/-/blob/main/docs/v1...
[3]: https://gitlab.com/cryptsetup/cryptsetup/-/merge_requests/93...
शायद बात उन setups की हो रही है जो
luksSuspendके बाद RAM suspend को वास्तव में उपयोगी तरीके से चलाते हैं; शुरू में यह Debian के लिए था और बाद में Arch में भी आया, लेकिन दोनों में यह default नहीं थामुझे कोई और अच्छा तरीका नहीं दिखता। power saving, यानी RAM suspend, में सब कुछ RAM में ही रहता है और encrypted होता है, लेकिन मेरी याद के अनुसार master key kernel memory में बनी रहती है
जबकि hibernate, यानी disk suspend, में RAM की पूरी सामग्री master key सहित disk पर लिखी जाती है और encrypt की जाती है, और RAM साफ़ हो जाती है
दोबारा जगाने पर disk की सामग्री वापस memory में लाने के लिए master key को decrypt करना पड़ता है, इसलिए passphrase फिर से दर्ज करनी होती है
लेकिन Debian ने पहले एक optional
cryptsetup-suspendaddon बनाया था, जोluksSuspendcommand चलाता है — जिसे memory से keys हटाने के लिए डिज़ाइन किया गया है — और फिर resume पर passphrase दोबारा माँगता हैkernel 6.8 तक यह बताए गए तरीके से काम करता था, लेकिन kernel 6.9 से यह चुपचाप काम करना बंद कर गया
इस feature को enable कर दें तो cold boot attacks लगभग बीती बात हो जाते हैं। आम तौर पर RAM speed में लगभग 0.5% की कमी के कारण यह default रूप से बंद रहता है
Sleep के बाद boot password दोबारा नहीं माँगा जाता, इसलिए यह साफ़ है कि encryption key अभी भी memory में मौजूद है
cryptsetup-luksSuspendइस्तेमाल नहीं कर रहामेरे लिए यह बहुत बड़ी चिंता की बात नहीं है
disk encryption करने का मेरा एकमात्र कारण यह है कि laptop बेचते समय कोई मेरे tax documents या credit card जानकारी में ताक-झाँक न कर सके
बेशक मैं laptop को wipe भी करता हूँ, लेकिन अगर data drive level पर encrypted हो, तो forensic tools जैसी चीज़ों से data recover हो जाने का जोखिम मुझे बहुत कम लगता है
LUKS एक anti-forensic algorithm इस्तेमाल करता है जिसमें disk खोलने के लिए पूरी volume key चाहिए होती है। key blocks को diffusion algorithm से मिलाकर और XOR करके असली master key बनाई जाती है, इसलिए सिद्धांततः volume key का सिर्फ एक sector मिटा देने पर भी पूरी चीज़ recover नहीं होनी चाहिए
यानी अगर key का एक भी block गायब हो, तो बाकी हिस्सों का आसानी से अनुमान नहीं लगाया जा सकता
मैं security expert बिल्कुल नहीं हूँ, लेकिन हाल में जिस तरह “refactoring के दौरान files के आर-पार जाने वाली C check की एक line छूट जाने” से बने गंभीर security bug नियमित रूप से मिल रहे हैं, उसे देखकर विशाल सुरक्षित open source C codebase वाली धारणा ही संदिग्ध लगती है
यह सिर्फ C की समस्या नहीं है, लेकिन खासकर C में invariants को लगातार enforce और track करना ज्यादा कठिन लगता है, और code change के समय तो और भी
यह भी नहीं पता कि invariants को type में encode करने वाली functional programming व्यावहारिक रूप से scalable समाधान है या नहीं। Model checking? LLM fuzzing? साफ सीमाओं वाले कम primitive elements? क्या seLinux को भी इसी तरह “verify” किया गया था?
मूल रूप से बात कुछ ऐसी है:
original:
DoTheThing()new:
DoTheThingSlightlyDifferentButKeepMyCredentialsAlive()fix:
DoTheThingSlightlyDifferentButDoInFactNOTKeepMyCredentialsAlive()मेरे अनुभव में मुश्किल bugs का एक बड़ा हिस्सा उच्च-स्तरीय system invariants के उल्लंघन से आता है, और यह ऐसी चीज़ नहीं लगती जिसे आसानी से automate किया जा सके
Lean जैसी किसी चीज़ से यह साबित किया जा सकता है कि program कुछ properties पूरी करता है, लेकिन पहले वह property सूझनी भी चाहिए। Proof अपने-आप invariant खोजकर नहीं देता
अगर संबंधित security property दिमाग में आ गई होती, तो regression test लिखना मुश्किल नहीं होता। सच में कठिन हिस्सा implementation को सुरक्षित रूप में व्यक्त करना नहीं, बल्कि यह समझना है कि implementation को कोई property preserve भी करनी है
समस्या यह है कि auditability ज्यादा होने का मतलब यह नहीं कि उसका audit अपने-आप ज्यादा होगा
इसके लिए पर्याप्त skill वाले लोगों को पर्याप्त समय देकर काम करना पड़ता है
यह अलग-अलग concerns के overlap और domains के बीच knowledge की कमी से बना bug है। Lisp या assembly में भी शायद यही होता
दूसरे शब्दों में, क्या security issue है इसकी कोई सख्त परिभाषा नहीं है
क्या federal agencies को key हासिल करने का कोई रास्ता बहुत ज़रूरी था? क्या यह bugdoor है? क्या commit tracing हुई?
हाल में ऐसे pattern बहुत दिख रहे हैं, इसलिए थोड़ा शक होने लगा है। यह भी हो सकता है कि लोग अब इस पर ज्यादा संवेदनशील हैं, इसलिए ज्यादा पोस्ट कर रहे हों
सिर्फ इतना कि encryption key memory में है, इसका मतलब यह नहीं कि उसे तुरंत निकाला जा सकता है। यह ज्यादा उस बात के करीब है कि उसे वहाँ नहीं होना चाहिए था, फिर भी वह अनावश्यक रूप से अनिश्चित समय तक पड़ी रही
ऐसे regression छूटना आसान होता है क्योंकि सब कुछ लगातार “काम” करता रहता है। Security bug अक्सर खुद को सामने नहीं लाते
इन्हें लिखना मज़ेदार भी था, और इनकी वजह से
git-bisectचलाकर उस खास kernel refactoring को ढूँढा जा सका जिसने यह bug introduce किया था: https://github.com/NixOS/nixpkgs/pull/532499मेरे Fedora laptop पर Linux को इस तरह सेट किया गया है कि suspend के 15 मिनट बाद disk पर hibernate हो जाए। अगर memory power बंद हो जाती है, तो ऐसा Debian-specific bug समस्या नहीं बनता
सिद्धांत में Debian के Linux tool extensions अच्छे हैं, लेकिन अगर आप वास्तव में cold boot attack की चिंता करते हैं, तो सिर्फ LUKS keys नहीं बल्कि सभी keys और महत्वपूर्ण documents भी memory से मिट जाने चाहिए
इसलिए cold boot को रोकने का सही तरीका आखिरकार hibernate ही है
जहाँ तक मुझे पता है, TPM का उपयोग किए बिना यह व्यावहारिक नहीं है। और TPM इस्तेमाल करें तो व्यावहारिक रूप से आप अपनी किस्मत TPM के भरोसे छोड़ रहे हैं
अगर यह vulnerability किसी commercial operating system में होती, तो बस कल्पना कीजिए यह HN thread कैसा दिखता
सबसे ऊपर वाला comment निश्चित रूप से यह कहता कि Applosoft अब software quality की परवाह नहीं करता, या “जब आप OS में vibe-coding कचरा आने देते हैं तो यही होता है”
उसके नीचे वाले comments surveillance industrial complex और NSA पर conspiracy theories से भरे होते; दूसरी जगह यह पागलपन लगता, लेकिन HN पर शायद नहीं
समझ नहीं आता कि इतनी महत्वपूर्ण चीज़ हर build पर test क्यों नहीं होती