दिलचस्प बिंदु; अधिकांश बफर ओवररन्स अंत से पहले नहीं जाते हैं, शुरुआत से पहले नहीं, इसलिए यह लगभग निश्चित रूप से मदद करेगा। कंपाइलर स्थानीय सरणी को स्टैक फ्रेम में उच्चतम पते पर डाल सकते हैं, इसलिए सरणी के बाद स्थित ओवरराइट करने के लिए कोई स्केलर स्थानीय नहीं होगा।
यदि आप स्थानीय सरणी के पते को किसी अन्य फ़ंक्शन में पास करते हैं, तो अभी भी खतरे है। क्योंकि बुलाए गए फ़ंक्शन का रिटर्न पता केवल सरणी के अंत में स्थित होगा।
unsafe() {
char buf[128];
gets(buf); // stack grows upward: exploit happens when gets executes `ret`
// stack grows down: exploit happens when the `ret` at the end of *this* function executes.
}
तो शायद एक बहुत बफर लगने की अभी भी संभव हो जाएगा। यह विचार केवल बफर ओवररन्स को हरा देता है जब असुरक्षित सरणी-लेखन कोड रेखांकित किया जाता है, इसलिए ओवररन सरणी के ऊपर महत्वपूर्ण कुछ भी नहीं होता है।
हालांकि, बफर ओवररन्स के कुछ अन्य सामान्य कारणों को आसानी से रेखांकित किया जा सकता है, जैसे strcat
। ऊपर बढ़ते ढेर कभी-कभी मदद करेंगे।
सुरक्षा उपायों को उपयोगी होने के लिए मूर्खतापूर्ण होने की आवश्यकता नहीं है, इसलिए यह निश्चित रूप से कभी-कभी मदद करेगा। शायद किसी के लिए x86 जैसे मौजूदा आर्किटेक्चर को बदलना नहीं है, लेकिन नए आर्किटेक्चर के लिए एक दिलचस्प विचार है। स्टैक-ग्रो-डाउन सीपीयू में लगभग सार्वभौमिक मानक है, हालांकि। क्या कुछ ऊपर की ओर बढ़ते कॉल स्टैक का उपयोग करता है? वास्तव में उस धारणा पर कितना सॉफ्टवेयर निर्भर करता है? उम्मीद है कि बहुत ज्यादा नहीं ...
पारंपरिक लेआउट ढेर और/या ढेर विकसित करने के लिए, केवल एक समस्या खड़ी कर रहा है, तो वे बीच में पूरा के लिए छोड़ दिया कक्ष।
अनुमानित कोड/डेटा पते पूर्वानुमानित स्टैक पते की तुलना में अधिक महत्वपूर्ण हैं, इसलिए अधिक रैम वाले कंप्यूटर डेटा/कोड से आगे निकल सकते हैं, जबकि स्थिर पते पर कोड/डेटा लोड करते समय भी। (यह बहुत ही हाथ से है। मैं खुद को भाग्यशाली मानता हूं कि वास्तविक 16-बिट प्रोग्राम नहीं लिखे हैं, और केवल सीजन के इस्तेमाल के बारे में सीखा है। शायद कोई भी जो अभी भी डॉस को याद करता है, वह यहां कुछ प्रकाश डाल सकता है कि यह अच्छा काम क्यों करता है अपने सेगमेंट के नीचे एक ऊपर की ओर बढ़ते ढेर और शीर्ष पर डेटा/कोड के बजाय, एक उच्च पते पर ढेर करें। उदाहरण के लिए "छोटे" कोड मॉडल के साथ जहां सब कुछ एक सेगमेंट में है)।
इस व्यवहार को बदलने के लिए एक ही असली मौका AMD64 है, जो पहली बार 86 कभी सच अनुकूलता पीछे की ओर टूट गया है है के साथ किया गया था। आधुनिक इंटेल सीपीयू अभी भी 8086 अनियंत्रित ओपोड्स का समर्थन करते हैं जैसे D6
: SALC
(Set AL from Carry Flag), आईएसए एक्सटेंशन के लिए कोडिंग स्पेस को सीमित करते हैं। (उदाहरण के लिएSSSE3 and SSE4 instructions would be 1 byte shorter अगर इंटेल ने अनियंत्रित ओपोड के लिए समर्थन छोड़ दिया।
फिर भी, यह केवल नए मोड के लिए होगा; एएमडी 64 सीपीयू को अभी भी विरासत मोड का समर्थन करना है, और जब 64-बिट मोड में उन्हें कंपैट मोड के साथ लंबे मोड को मिश्रण करना होता है (आमतौर पर 32-बिट उपयोगकर्ता-स्पेस प्रक्रियाओं को 32-बिट बाइनरी से चलाने के लिए)।
AMD64 शायद एक स्टैक-दिशा ध्वज जोड़ सकता है, लेकिन इससे हार्डवेयर अधिक जटिल हो जाता। जैसा कि मैंने उपरोक्त तर्क दिया है, मुझे नहीं लगता कि यह सुरक्षा के लिए एक बड़ा लाभ होगा। अन्यथा, शायद एएमडी आर्किटेक्ट्स ने इसे माना होगा, लेकिन अभी भी असंभव है। वे निश्चित रूप से कम से कम घुसपैठ करने का लक्ष्य रख रहे थे, और यह सुनिश्चित नहीं था कि यह पकड़ जाएगा। वे अपने सीपीयू में एएमडी 64 संगतता बनाए रखने के लिए अतिरिक्त सामान के साथ फंसना नहीं चाहते थे अगर दुनिया ज्यादातर 32-बिट ओएस और 32-बिट कोड चलती रहती है।
यह शर्म की बात है, क्योंकि वहां बहुत सी मामूली चीजें हैं जो संभवतः निष्पादन इकाइयों में बहुत अधिक ट्रांजिस्टर की आवश्यकता नहीं होती थीं। (उदाहरण के लिए लंबे मोड में, के साथ setcc r/m8
को प्रतिस्थापित करें)।
शायद आपका प्रश्न [सुरक्षा स्टैक एक्सचेंज।] में बेहतर फिट बैठता है (http://security.stackexchange.com/) –
@RyanB मुझे ऐसा नहीं लगता है। प्रश्न यह है कि सुरक्षा समस्या के बावजूद ढेर बढ़ रहा है * (जो कि वास्तव में "अस्तित्व में नहीं था" जब x86 डिज़ाइन किया गया था)। –
यह देखते हुए कि 8086 सिर्फ एक विनम्र माइक्रोकंट्रोलर के रूप में पैदा हुआ था, मुझे संदेह है कि किसी ने किसी भी नेटवर्क पर दुर्भावनापूर्ण उपयोगकर्ताओं से आने वाले अविश्वसनीय डेटा के खिलाफ डाउन-बढ़ते ढेर के सुरक्षा प्रभाव को माना है। ;-) –