1 पॉइंट द्वारा GN⁺ 3 시간 전 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • 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/keys entries देखने से शुरू हुई, और 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-suspend project 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 टिप्पणियां

 
GN⁺ 3 시간 전
Hacker News की राय
  • यह निश्चित रूप से एक दिलचस्प bug है, लेकिन शीर्षक थोड़ा clickbait जैसा लगता है
    मेरी समझ के अनुसार cryptsetup luksSuspend कोई आधिकारिक रूप से समर्थित फीचर कम और Debian द्वारा बनाया गया extension ज़्यादा है, इसलिए शायद यह regression भी सिर्फ Debian को ही प्रभावित करता था
    जो फीचर न तो supported है और न ही व्यापक रूप से tested, उसके लिए kernel को दोष देना चाहिए या नहीं, यह साफ़ नहीं है
    फिर भी यह काफ़ी प्रभावशाली है, और अच्छा है कि ऐसा regression दोबारा न आए इसके लिए अब test मौजूद है। OP की NixOSTests वाली राय से भी मैं पूरी तरह सहमत हूँ
    हालाँकि सिर्फ शीर्षक पढ़ने पर यह किसी एक distribution की बजाय व्यापक समस्या जैसा लगता है

    • मेरा उद्देश्य तकनीकी रूप से सटीक शीर्षक रखना था, clicks बटोरना नहीं
      सही है। जो लोग 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 के ज़रिए इसी गुण को तोड़ दिया
    • मुझे समझ नहीं आता कि इसे Debian-only क्यों कहा जा रहा है। luksSuspend upstream feature है और 2009 में v1.1.0 release में जोड़ा गया था
      मैंने इसे पहले 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...
    • subcommand आधिकारिक cryptsetup repository में मौजूद है और उसका विवरण भी सही लगता है: https://gitlab.com/cryptsetup/cryptsetup/-/blob/main/man/cry...
    • मैंने यह फीचर Arch पर इस्तेमाल किया है, और इसे सामान्य LUKS के साथ भी इस्तेमाल किया जा सकता है। हालाँकि मेरी जानकारी में suspend के समय यह default रूप से इस्तेमाल नहीं होता
      शायद बात उन setups की हो रही है जो luksSuspend के बाद RAM suspend को वास्तव में उपयोगी तरीके से चलाते हैं; शुरू में यह Debian के लिए था और बाद में Arch में भी आया, लेकिन दोनों में यह default नहीं था
    • यह जानने की जिज्ञासा है कि Debian के किस version ने सबसे पहले 6.9 ship किया
  • मुझे कोई और अच्छा तरीका नहीं दिखता। 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 फिर से दर्ज करनी होती है

    • सही। ज़्यादातर default Linux distributions में अगर आप बस laptop को suspend करते हैं, तो master key सहित सब कुछ memory में बना रहता है
      लेकिन Debian ने पहले एक optional cryptsetup-suspend addon बनाया था, जो luksSuspend command चलाता है — जिसे memory से keys हटाने के लिए डिज़ाइन किया गया है — और फिर resume पर passphrase दोबारा माँगता है
      kernel 6.8 तक यह बताए गए तरीके से काम करता था, लेकिन kernel 6.9 से यह चुपचाप काम करना बंद कर गया
    • पिछले लगभग 5 साल के Intel/AMD CPU, दोनों, ऐसी full memory encryption को support करते हैं जो operating system के लिए transparent होती है
      इस feature को enable कर दें तो cold boot attacks लगभग बीती बात हो जाते हैं। आम तौर पर RAM speed में लगभग 0.5% की कमी के कारण यह default रूप से बंद रहता है
  • Sleep के बाद boot password दोबारा नहीं माँगा जाता, इसलिए यह साफ़ है कि encryption key अभी भी memory में मौजूद है

    • यह भी साफ़ है कि distribution cryptsetup-luksSuspend इस्तेमाल नहीं कर रहा
  • मेरे लिए यह बहुत बड़ी चिंता की बात नहीं है
    disk encryption करने का मेरा एकमात्र कारण यह है कि laptop बेचते समय कोई मेरे tax documents या credit card जानकारी में ताक-झाँक न कर सके
    बेशक मैं laptop को wipe भी करता हूँ, लेकिन अगर data drive level पर encrypted हो, तो forensic tools जैसी चीज़ों से data recover हो जाने का जोखिम मुझे बहुत कम लगता है

    • एक ठीक-ठाक समझौता यह है कि सिर्फ LUKS header मिटा दिया जाए
      LUKS एक anti-forensic algorithm इस्तेमाल करता है जिसमें disk खोलने के लिए पूरी volume key चाहिए होती है। key blocks को diffusion algorithm से मिलाकर और XOR करके असली master key बनाई जाती है, इसलिए सिद्धांततः volume key का सिर्फ एक sector मिटा देने पर भी पूरी चीज़ recover नहीं होनी चाहिए
      यानी अगर key का एक भी block गायब हो, तो बाकी हिस्सों का आसानी से अनुमान नहीं लगाया जा सकता
    • अगर मान लिया जाए कि encryption keys मज़बूत हैं, तो wiping सैद्धांतिक रूप से दोहराव वाला काम है
  • मैं 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” किया गया था?

    • C की कमियाँ दिखती हैं और मैं नए project के लिए आम तौर पर इसकी recommendation भी नहीं करता, लेकिन मुझे नहीं लगता कि यह खास bug ऐसा अच्छा उदाहरण है जिसे Rust का borrow checker या किसी दूसरी language का type system पकड़ लेता। Static analyzer भी शायद इसे नहीं पकड़ पाता
      मूल रूप से बात कुछ ऐसी है:
      original: DoTheThing()
      new: DoTheThingSlightlyDifferentButKeepMyCredentialsAlive()
      fix: DoTheThingSlightlyDifferentButDoInFactNOTKeepMyCredentialsAlive()
      मेरे अनुभव में मुश्किल bugs का एक बड़ा हिस्सा उच्च-स्तरीय system invariants के उल्लंघन से आता है, और यह ऐसी चीज़ नहीं लगती जिसे आसानी से automate किया जा सके
      Lean जैसी किसी चीज़ से यह साबित किया जा सकता है कि program कुछ properties पूरी करता है, लेकिन पहले वह property सूझनी भी चाहिए। Proof अपने-आप invariant खोजकर नहीं देता
      अगर संबंधित security property दिमाग में आ गई होती, तो regression test लिखना मुश्किल नहीं होता। सच में कठिन हिस्सा implementation को सुरक्षित रूप में व्यक्त करना नहीं, बल्कि यह समझना है कि implementation को कोई property preserve भी करनी है
    • सुरक्षित public codebase वाली धारणा अपने-आप में ठीक है
      समस्या यह है कि auditability ज्यादा होने का मतलब यह नहीं कि उसका audit अपने-आप ज्यादा होगा
      इसके लिए पर्याप्त skill वाले लोगों को पर्याप्त समय देकर काम करना पड़ता है
    • Rust में translate करने पर भी बात शायद “Rust check की एक line छूट गई” ही बनती
      यह अलग-अलग concerns के overlap और domains के बीच knowledge की कमी से बना bug है। Lisp या assembly में भी शायद यही होता
    • यहाँ से मिलने वाला सबक यह है कि अगर किसी feature के लिए कम-से-कम संबंधित test case नहीं है, तो वह असल में feature नहीं है
    • विशाल सुरक्षित open source C codebase वाली धारणा इसलिए संदिग्ध लगती है, क्योंकि code review कभी-कभी specification के formalized version तक पहुँच वाले एक idealized halting problem से बहुत अलग नहीं होता
      दूसरे शब्दों में, क्या security issue है इसकी कोई सख्त परिभाषा नहीं है
  • क्या federal agencies को key हासिल करने का कोई रास्ता बहुत ज़रूरी था? क्या यह bugdoor है? क्या commit tracing हुई?
    हाल में ऐसे pattern बहुत दिख रहे हैं, इसलिए थोड़ा शक होने लगा है। यह भी हो सकता है कि लोग अब इस पर ज्यादा संवेदनशील हैं, इसलिए ज्यादा पोस्ट कर रहे हों

    • यह regression है। User-space application भी चुपचाप fail हुआ होगा, और यह कई तरह की लापरवाही के जुड़ने का नतीजा है
      सिर्फ इतना कि encryption key memory में है, इसका मतलब यह नहीं कि उसे तुरंत निकाला जा सकता है। यह ज्यादा उस बात के करीब है कि उसे वहाँ नहीं होना चाहिए था, फिर भी वह अनावश्यक रूप से अनिश्चित समय तक पड़ी रही
  • ऐसे regression छूटना आसान होता है क्योंकि सब कुछ लगातार “काम” करता रहता है। Security bug अक्सर खुद को सामने नहीं लाते

    • सही। इसलिए ऐसे feature के लिए integration test और भी महत्वपूर्ण हैं
      इन्हें लिखना मज़ेदार भी था, और इनकी वजह से 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 ही है

    • सहमत। या फिर FridgeLock को वापस जिंदा करने का तरीका भी है: https://www.sec.in.tum.de/i20/publications/fridgelock-preven...
    • लेकिन resume के समय memory को decrypt करने वाली key कहाँ से आएगी?
      जहाँ तक मुझे पता है, 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 क्यों नहीं होती