flawopen.com/मेमोरी सुरक्षा/Rust unsafe
क्या Rust का unsafe ब्लॉक मेमोरी-सुरक्षित है?
unsafe Rust की जाँच बंद नहीं करता। यह उन खास operations की अनुमति देता है जिनकी सुरक्षा compiler साबित नहीं कर सकता; उन शर्तों को पूरा करना प्रोग्रामर की जिम्मेदारी है। इसलिए असाउंड unsafe abstraction साधारण सुरक्षित callers से undefined behaviour (UB) करा सकता है, भले ही उन्होंने unsafe न लिखा हो।
मुख्य शब्द
- Unsafe operation:
- ऐसा operation जिसकी सुरक्षा शर्त compiler साबित नहीं कर सकता, जैसे raw pointer को dereference करना।
- Sound abstraction:
- ऐसा सुरक्षित API जिसके सुरक्षित callers undefined behaviour नहीं करा सकते।
- size_hint():
- अनुकूलन के लिए iterator के आकार का अनुमान; यह सटीक गिनती या मेमोरी-सुरक्षा का प्रमाण नहीं है।
- Undefined behaviour (UB):
- ऐसा प्रोग्राम व्यवहार जिसे Rust परिभाषित नहीं करता; unsafe कोड को सुरक्षित callers से इसे होने से रोकना चाहिए।
असुरक्षित सुरक्षित abstraction कैसे विफल होता है
सुरक्षित API iterator लेता है
Caller साधारण iterator को ऐसे फ़ंक्शन में देता है जिसकी कोई unsafe precondition नहीं है।
Implementation अनुमान के आधार पर जगह लेता है
फ़ंक्शन बताई गई न्यूनतम संख्या के लिए ही जगह लेता है, जो iterator द्वारा दिए जाने वाले वास्तविक items से कम हो सकती है।
बिना जाँच लिखने से क्षमता पार होती है
Implementation allocation बढ़ाए या हर item पर क्षमता जाँचे बिना raw pointer से सभी items लिखता है।
सुरक्षित उपयोग UB तक पहुँचता है
यदि items की संख्या उपलब्ध जगह से अधिक है, तो सुरक्षित call सीमा से बाहर लिख सकता है। Vec::extend या सुरक्षित रूप से बढ़ने वाला implementation उपयोग करें।
// UNSOUND: reserve uses only the lower hint, // then unchecked writes consume every item. fn append_unsound(dst: &mut Vec<u8>, iter: impl Iterator<Item = u8>) { let (lower, _) = iter.size_hint(); dst.reserve(lower); let start = dst.len(); let mut written = 0; unsafe { let out = dst.as_mut_ptr().add(start); for item in iter { // UB once writes exceed spare capacity. out.add(written).write(item); written += 1; } dst.set_len(start + written); } }
// SOUND: Vec::extend handles capacity // growth and length updates safely. fn append(dst: &mut Vec<u8>, iter: impl Iterator<Item = u8>) { dst.extend(iter); }
Rust की गारंटी का वास्तविक अर्थ
सटीक गारंटी है: यदि सुरक्षित Rust जिस unsafe कोड पर निर्भर है वह sound है, तो सुरक्षित Rust undefined behaviour नहीं करा सकता।Rust Reference सीमा पर soundness परिभाषित करता है: unsafe कोड को सुनिश्चित करना चाहिए कि सुरक्षित clients UB न करा सकें। Compiler unsafe operation के भीतर हर proof obligation की जाँच नहीं करता; प्रोग्रामर और reviewers को उन्हें पूरा करना होता है।
C और C++ की तुलना में यह Rust का बड़ा व्यावहारिक लाभ है: Rust मेमोरी-संवेदनशील operations और उनकी सुरक्षा जिम्मेदारियों को अधिक स्पष्ट करता है। इससे reviewers unsafe boundaries और उन पर बनी सुरक्षित abstractions पर ध्यान दे सकते हैं। इनमें unsafe blocks, unsafe function contracts, unsafe trait implementations, FFI declarations और unsafe attributes शामिल हैं; ये हमेशा एक छोटे block तक सीमित नहीं होते। उदाहरण है smallvec का CVE-2021-25900: SmallVec::insert_many ने iterator के size hint की न्यूनतम सीमा के आधार पर जगह ली, फिर allocation से अधिक items लिखे; CVSS 9.8 था।
मानदंड soundness है, केवल सावधानी नहीं
यदि सुरक्षित कोड किसी API का उपयोग करके undefined behaviour करा सकता है, तो वह API unsound है। उदाहरण के लिए, Iterator::size_hint अनुकूलन के लिए सीमाएँ देता है, सटीक item count नहीं: वैध iterator न्यूनतम सीमा से अधिक items दे सकता है और त्रुटिपूर्ण iterator अपना अनुमान तोड़ सकता है। दस्तावेज़ स्पष्ट कहता है कि इस hint के आधार पर unsafe कोड में bounds checks न हटाएँ। सुरक्षित trait का गलत व्यवहार logic errors या panic भी करा सकता है; वे अपने आप UB नहीं होते, फिर भी caller के अप्रत्याशित व्यवहार के दौरान unsafe कोड को memory invariants बनाए रखने चाहिए।
इसलिए unsafe कोड का असर कई जगहों तक जा सकता है: एक स्थान पर स्थापित memory invariant को ऊपर के सुरक्षित APIs मान सकते हैं। invariant गलत हो तो दोष उस abstraction में है जिसने सुरक्षित API उपलब्ध कराया, उन callers में नहीं जो contract के अनुसार उसका उपयोग करते हैं।
व्यावहारिक नियम
- ✓सुरक्षित trait methods को memory-safety proof न मानें।
size_hint()केवल optimization के लिए है; checks बनाए रखें या जरूरत पर capacity बढ़ाएँ। - ✓Panic के दौरान invariants बनाए रखें।
Iterator::next, destructor या closure जैसे caller-provided code से unwind हो सकता है। सुनिश्चित करें कि आंशिक रूप से initialized स्थिति वैध रहे और सही तरह drop हो। - ✓
// SAFETY:टिप्पणी लिखें और आवश्यक शर्तें तथा उनके पूरा होने का कारण बताएँ। बिना स्पष्टीकरण वाला unsafe review नहीं किया जा सकता। - ✓Blocks छोटे रखें। keyword दोहराने से बचने के लिए पूरी loop को unsafe में लपेटना reviewer के तर्क क्षेत्र को बढ़ाता है।
- ✓चलाए गए paths वाले tests पर Miri चलाएँ। यह executed paths में कुछ UB, जैसे out-of-bounds access, use-after-free और invalid aliasing, पकड़ सकता है; यह soundness का प्रमाण नहीं है।
- ✓Dependencies audit करें।
cargo auditज्ञात RustSec advisories जाँचता है;cargo geigerunsafe उपयोग सूचीबद्ध करने में मदद करता है। कोई भी shipped unsafe contracts के review का विकल्प नहीं है।
अक्सर पूछे जाने वाले प्रश्न
#![forbid(unsafe_code)] जिस crate में सक्षम हो वहाँ unsafe syntax रोक सकता है, जो application crates के लिए उपयोगी है। यह dependencies पर लागू नहीं होता; कुछ implementations, FFI boundaries और libraries को unsafe operations चाहिए।
हाँ। unsafe trait implementers की जिम्मेदारियाँ बताता है, जिन पर unsafe कोड निर्भर कर सकता है। TrustedLen standard library का unstable trait है, जो सटीक size hint का वादा करने वाले iterators के लिए है। सामान्य Iterator::size_hint यह गारंटी नहीं देता।
नहीं। Rust का safety model memory-safety obligations के दायरे को सीमित करता है और unsafe boundaries पर उन्हें स्पष्ट करता है। unsafe कोड, dependencies, FFI contracts और unsafe implementations पर बने सुरक्षित APIs का audit फिर भी जरूरी है।
संदर्भ
- The Rust Reference — unsafe code and soundness
- Rust Reference — the unsafe keyword and proof obligations
- Rust standard library — Iterator::size_hint contract
- Rustonomicon — working with unsafe
- RustSec Advisory RUSTSEC-2021-0003 — smallvec buffer overflow
- GitHub Security Advisory GHSA-43w2-9j62-hq99 — CVE-2021-25900
- The Rustonomicon — the guide to unsafe Rust
- RustSec Advisory Database
- Miri — an interpreter that detects undefined behaviour
- CWE-787 — Out-of-bounds Write
- Case study: the smallvec overflow (CVE-2021-25900)