ओवरफ्लोज़ को सी कम करने के लिए सी को कम करना इतना मुश्किल क्यों है?


23

मैं कॉलेज में एक कोर्स कर रहा हूं, जहां प्रयोगशालाओं में से एक कोड पर बफर अतिप्रवाह कारनामे करना है जो वे हमें देते हैं। यह साधारण कारनामों से लेकर जैसे किसी फ़ंक्शन के लिए रिटर्न एड्रेस को स्टैक पर बदलने के लिए एक अलग फ़ंक्शन पर लौटने के लिए, सभी तरह से कोड के लिए जो प्रोग्राम रजिस्टर / मेमोरी स्टेट को बदलता है लेकिन फिर उस फ़ंक्शन पर वापस जाता है जिसे आपने कॉल किया था, जिसका अर्थ है फंक्शन जिसे आप कहते हैं, शोषण के लिए पूरी तरह से बेखबर है।

मैंने इस पर कुछ शोध किया, और इस तरह के कारनामों का उपयोग आज भी हर जगह किया जाता है, यहाँ तक कि Wii पर होमब्रे चलाने जैसे कामों में , और iOS 4.3.1 के लिए अनैतिक जेलब्रेक

मेरा सवाल यह है कि इस समस्या को ठीक करना इतना मुश्किल क्यों है? यह स्पष्ट है कि यह सैकड़ों चीजों को हैक करने के लिए इस्तेमाल किया जाने वाला एक प्रमुख कारनाम है, लेकिन ऐसा लगता है कि अनुमत लंबाई से पहले किसी भी इनपुट को काटकर, और केवल आपके द्वारा किए गए सभी इनपुट को सैनिटाइज़ करके इसे ठीक करना बहुत आसान होगा।

संपादित करें: एक और परिप्रेक्ष्य जो मैं विचार करने के लिए उत्तर चाहता हूं - सी के निर्माता पुस्तकालयों को फिर से लागू करके इन मुद्दों को ठीक क्यों नहीं करते हैं?

जवाबों:


35

उन्होंने पुस्तकालयों को ठीक किया।

किसी भी आधुनिक सी मानक पुस्तकालय का सुरक्षित वेरिएंट शामिल strcpy, strcat, sprintf, और इतने पर।

C99 सिस्टम पर - जो कि अधिकांश यूनिक्स है - आपको ये मिलेंगे जैसे नाम के साथ strncatऔर snprintf, "n" यह दर्शाता है कि यह एक तर्क लेता है कि एक बफर या कॉपी करने के लिए अधिकतम तत्वों की संख्या है।

इन कार्यों का उपयोग कई कार्यों को अधिक सुरक्षित रूप से संभालने के लिए किया जा सकता है, लेकिन पूर्वव्यापीकरण में उनकी प्रयोज्यता महान नहीं है। उदाहरण के लिए कुछ snprintfकार्यान्वयन की गारंटी नहीं है कि बफर शून्य-समाप्त है। strncatकॉपी करने के लिए कई तत्व हैं, लेकिन कई लोग गलती से बेस बफर के आकार को पार कर जाते हैं।

Windows पर, एक अक्सर पाता है strcat_s, sprintf_s"_s" प्रत्यय का संकेत "सुरक्षित"। ये भी C11 में C मानक पुस्तकालय में अपना रास्ता खोज चुके हैं, और अतिप्रवाह (उदाहरण के लिए अभिकर्मक बनाम छंटनी) की स्थिति में क्या होता है, इस पर अधिक नियंत्रण प्रदान करते हैं।

कई विक्रेता asprintfजीएनयू परिवाद की तरह और भी अधिक गैर-मानक विकल्प प्रदान करते हैं , जो स्वचालित रूप से उपयुक्त आकार के एक बफर को आवंटित करेगा।

यह विचार कि आप "सी को ठीक कर सकते हैं" एक गलतफहमी है। सी को ठीक करना समस्या नहीं है - और पहले से ही किया गया है। समस्या सी कोड के दशकों को अज्ञानी, थके हुए, या जल्दबाज़ प्रोग्रामर द्वारा लिखे गए कोड को ठीक कर रही है, या उस कोड को संदर्भों से चित्रित किया गया है जहां सुरक्षा संदर्भों से कोई फर्क नहीं पड़ता जहां सुरक्षा करता है। मानक लाइब्रेरी में कोई परिवर्तन इस कोड को ठीक नहीं कर सकता है, हालांकि नए संकलक और मानक पुस्तकालयों में प्रवास अक्सर समस्याओं को स्वचालित रूप से पहचानने में मदद कर सकता है।


11
+1 प्रोग्रामर पर समस्या को लक्षित करने के लिए, भाषा नहीं।
निकोल बोल

8
@ नाइकोल: "समस्या [प्रोग्रामर है" कहना गलत तरीके से कम करने वाला है। समस्या यह है कि वर्षों (दशकों) तक सी ने सुरक्षित कोड की तुलना में असुरक्षित कोड लिखना आसान बना दिया, विशेष रूप से "सुरक्षित" की हमारी परिभाषा किसी भी भाषा मानक की तुलना में तेजी से विकसित हुई, और यह कि कोड अभी भी आसपास है। यदि आप उस एकल संज्ञा को कम करने का प्रयास करना चाहते हैं, तो समस्या "1970-1999 libc" है, न कि "प्रोग्रामर।"

1
यह अभी भी प्रोग्रामर की जिम्मेदारी है कि इन समस्याओं को ठीक करने के लिए उनके पास जो उपकरण हैं उनका उपयोग करें । एक आधा दिन या तो ले लो और इन चीजों के लिए स्रोत कोड के माध्यम से कुछ कर लो।
निकोल बोल

1
@ नाइकोल: हालांकि एक संभावित बफर ओवरफ्लो का पता लगाने के लिए तुच्छ, यह निश्चित रूप से होने के लिए अक्सर तुच्छ नहीं है कि यह एक वास्तविक खतरा है, और बफर कम होने पर क्या होना चाहिए यह काम करने के लिए कम तुच्छ है। त्रुटि से निपटने / अक्सर नहीं माना जाता था, एक सुधार को "जल्दी से" लागू करना संभव नहीं है क्योंकि आप अप्रत्याशित तरीके से मॉड्यूल के व्यवहार को बदल सकते हैं। हमने इसे बहु-मिलियन लाइन की विरासत कोड बेस में किया है, और हालांकि इसके लायक होने पर बहुत समय (और धन) खर्च होता है।
मट्टनज़

4
@ निचलोल: यह सुनिश्चित नहीं करें कि आप किस तरह की दुकान में काम करते हैं, लेकिन अंतिम बार मैंने उत्पादन उपयोग के लिए सी लिखा था, जिसमें विस्तृत डिजाइन डॉक में संशोधन करना, इसकी समीक्षा करना, कोड बदलना, परीक्षण योजना में संशोधन करना, परीक्षण योजना की समीक्षा करना, पूर्ण प्रदर्शन करना शामिल है। सिस्टम परीक्षण, परीक्षण के परिणामों की समीक्षा करना, फिर ग्राहक की साइट पर सिस्टम को फिर से प्रमाणित करना। यह एक ऐसे टेलीकॉम सिस्टम के लिए है, जो किसी ऐसी कंपनी के लिए लिखा गया है, जो अब मौजूद नहीं है। अंतिम मैं जानता था, स्रोत एक QIC टेप पर RCS संग्रह में था जो अभी भी पठनीय होना चाहिए , यदि आप एक उपयुक्त टेप ड्राइव पा सकते हैं।
टीएमएन

19

यह कहना वास्तव में गलत नहीं है कि सी वास्तव में डिजाइन द्वारा "त्रुटि-प्रवण" है । कुछ गंभीर गलतियों के अलावा gets, सी भाषा वास्तव में प्राथमिक सुविधा को खोए बिना किसी अन्य तरीके से नहीं हो सकती है जो लोगों को सी में पहली जगह पर खींचती है।

सी को "पोर्टेबल असेंबली" के रूप में कार्य करने के लिए सिस्टम भाषा के रूप में डिज़ाइन किया गया था। C भाषा की एक प्रमुख विशेषता यह है कि उच्च-स्तरीय भाषाओं के विपरीत, C कोड अक्सर वास्तविक मशीन कोड के बहुत निकट होता है। दूसरे शब्दों में, ++iआमतौर पर सिर्फ एक incनिर्देश है, और आप अक्सर एक सामान्य विचार प्राप्त कर सकते हैं कि प्रोसेसर सी कोड को देखकर रन-टाइम पर क्या कर रहा है।

लेकिन अंतर्निहित सीमा की जाँच में जोड़ने से अतिरिक्त ओवरहेड का बहुत कुछ जुड़ जाता है - जो कि प्रोग्रामर ने नहीं माँगा था और वह नहीं चाहता हो सकता है। यह ओवरहेड प्रत्येक सरणी की लंबाई को संग्रहीत करने के लिए आवश्यक अतिरिक्त संग्रहण से परे जाता है, या हर सरणी एक्सेस पर सरणी सीमा की जांच करने के लिए अतिरिक्त निर्देश। सूचक अंकगणित के बारे में क्या? या क्या होगा यदि आपके पास एक फ़ंक्शन है जो एक पॉइंटर में लेता है? रनटाइम वातावरण को यह जानने का कोई तरीका नहीं है कि क्या सूचक वैध रूप से आवंटित मेमोरी ब्लॉक की सीमा में आता है। इस पर नज़र रखने के लिए, आपको कुछ गंभीर रनटाइम आर्किटेक्चर की आवश्यकता होगी, जो वर्तमान में आवंटित मेमोरी ब्लॉक की तालिका के खिलाफ प्रत्येक पॉइंटर की जांच कर सकते हैं, जिस बिंदु पर हम पहले से ही जावा / सी # -स्टाइल प्रबंधित रनटाइम क्षेत्र में प्राप्त कर रहे हैं।


12
ईमानदारी से जब लोग पूछते हैं कि सी "सुरक्षित" क्यों नहीं है तो यह मुझे आश्चर्यचकित करता है कि क्या वे शिकायत करेंगे कि विधानसभा "सुरक्षित" नहीं है।
बेन ब्रोका

5
सी भाषा एक डिजिटल उपकरण निगम पीडीपी -11 मशीन पर पोर्टेबल असेंबली की तरह है। एक ही समय में Burroughs मशीनों में CPU में सरणी की जाँच की गई थी, इसलिए उन्हें सही में प्रोग्राम प्राप्त करना बहुत आसान था। Rockwell Collins हार्डवेयर में हार्डवेयर चेक में ऐरे चेक (ज्यादातर विमानन में उपयोग किया जाता है।)
टिम विलिसक्रॉफ्ट

15

मुझे लगता है कि असली समस्या यह नहीं है कि इस प्रकार के कीड़े को ठीक करना मुश्किल है, लेकिन यह है कि वे बनाने में आसान हैं: यदि आप उपयोग करते हैं strcpy, sprintfऔर (प्रतीत होता है) दोस्तों में सबसे सरल तरीका काम कर सकता है, तो आप शायद एक बफर अतिप्रवाह के लिए दरवाजा खोला। और कोई भी इसे तब तक नोटिस नहीं करेगा जब तक कि कोई इसका शोषण न करे (जब तक कि आपके पास बहुत अच्छे कोड समीक्षा न हों)। अब इस तथ्य को जोड़ें कि कई औसत दर्जे के प्रोग्रामर हैं और वे समय के सबसे अधिक दबाव में हैं - और आपके पास कोड के लिए एक नुस्खा है जो बफर ओवरफ्लो से इतना अधिक भरा हुआ है कि उन सभी को ठीक करना मुश्किल होगा क्योंकि वहाँ उनमें से बहुत से और वे इतनी अच्छी तरह से छिपा रहे हैं।


3
आपको वास्तव में "बहुत अच्छे कोड समीक्षाओं" की आवश्यकता नहीं है। आपको बस स्प्रिंटफ़ पर प्रतिबंध लगाने की ज़रूरत है, या फिर स्प्रिंटफ़ को किसी ऐसी चीज़ में परिभाषित करना है जो साइज़ोफ़ () और पॉइंटर के आकार पर त्रुटियों का उपयोग करता है, या आदि। आपको कोड समीक्षाओं की भी आवश्यकता नहीं है, आप SCM प्रतिबद्ध के साथ इस तरह का सामान कर सकते हैं हुक और grep।

1
@JoeWreschnig: sizeof(ptr)4 या 8, आम तौर पर है। यह एक और सी सीमा है: एक सरणी की लंबाई निर्धारित करने का कोई तरीका नहीं है, इसे केवल सूचक दिया गया है।
एमएसल्टर्स

@MSalters: हाँ, int [1] या चार [4] की एक सरणी या जो भी एक झूठी सकारात्मक हो सकती है, लेकिन व्यवहार में आप उन कार्यों के साथ कभी भी उस आकार के बफ़र्स को संभाल नहीं रहे हैं। (मैं यहां सैद्धांतिक रूप से नहीं बोल रहा हूं - मैंने चार साल तक एक बड़े सी कोड बेस पर काम किया, जिसने इस दृष्टिकोण का उपयोग किया। मैंने कभी भी एक चार []] में स्प्रिंटफिंग की सीमा नहीं मारा।

5
@ ब्लेकजैक: अधिकांश प्रोग्रामर बेवकूफ नहीं हैं - यदि आप उन्हें आकार पास करने के लिए मजबूर करते हैं, तो वे सही पास करेंगे। यह सिर्फ सबसे अधिक है जब तक कि आकार को मजबूर नहीं किया जाएगा। आप एक मैक्रो लिख सकते हैं जो एक सरणी की लंबाई लौटाएगा यदि यह स्थिर या ऑटो आकार है, लेकिन एक सूचक दिए जाने पर त्रुटियां। फिर आप उस मैक्रो को आकार देने के साथ स्निप्रफ को कॉल करने के लिए स्प्रिंटफ को # परिभाषित करते हैं। अब आपके पास स्प्रिंटफ का एक संस्करण है जो केवल ज्ञात आकारों के साथ सरणियों पर काम करता है, और प्रोग्रामर को स्निपरफ को मैन्युअल रूप से निर्दिष्ट आकार के साथ कॉल करने के लिए मजबूर करता है।

1
इस तरह के मैक्रो का एक सरल उदाहरण होगा, #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]) / (sizeof(a) != sizeof(void *))जो एक संकलन-समय विभाजन-दर-शून्य को ट्रिगर करेगा। क्रोमियम में एक और चतुर मैंने पहली बार देखा #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]) / !(sizeof(a) % sizeof((a)[0]))जो कुछ झूठी नकारात्मक के लिए मुट्ठी भर झूठी परंपराओं का व्यापार करता है - दुर्भाग्य से यह चार [] के लिए बेकार है। आप इसे और भी विश्वसनीय बनाने के लिए विभिन्न संकलक एक्सटेंशन का उपयोग कर सकते हैं, जैसे कि blogs.msdn.com/b/ce_base/archive/2007/05/08/…

7

बफर ओवरफ्लो को ठीक करना मुश्किल है क्योंकि सी समस्या को हल करने के लिए लगभग कोई उपयोगी उपकरण प्रदान नहीं करता है। यह एक मौलिक भाषा दोष है कि देशी बफ़र्स कोई सुरक्षा प्रदान नहीं करते हैं और यह वस्तुतः है, अगर पूरी तरह से असंभव नहीं है, तो उन्हें एक बेहतर उत्पाद के साथ प्रतिस्थापित करना, जैसे कि C ++ ने किया std::vectorऔर std::array, और बफर ओवरफ्लो का पता लगाने के लिए डिबग मोड के तहत भी यह कठिन है।


13
"भाषा दोष" एक भयानक पक्षपाती दावा है। पुस्तकालयों ने सीमा प्रदान नहीं की-जाँच एक दोष था; ओवरहेड से बचने के लिए भाषा जागरूक विकल्प नहीं थी। यह पसंद इस बात का हिस्सा है कि उच्च स्तर के निर्माणों std::vectorको कुशलता से लागू करने की अनुमति मिलती है । और vector::operator[]सुरक्षा पर गति के लिए एक ही विकल्प बनाता है। vectorआकार के चारों ओर गाड़ी चलाना आसान बनाने से होने वाली सुरक्षा , जो आधुनिक सी लाइब्रेरीज़ के समान दृष्टिकोण है।

1
@Charles: "C मानक पुस्तकालय के भाग के रूप में गतिशील रूप से विस्तार करने वाले बफ़र्स को किसी भी प्रकार प्रदान नहीं करता है।" नहीं, इससे कोई लेना-देना नहीं है। सबसे पहले, C उन्हें प्रदान करता है realloc(C99 आपको रनटाइम-निर्धारित लेकिन किसी भी स्वचालित चर के माध्यम से निरंतर आकार का उपयोग करके स्टैक सरणियों को आकार देने की अनुमति देता है, लगभग हमेशा बेहतर होता है char buf[1024])। दूसरा, समस्या का विस्तार करने वाले बफ़र्स से कोई लेना-देना नहीं है, इसका यह करना है कि क्या बफ़र्स उनके साथ आकार लेते हैं या नहीं और जब आप उन्हें एक्सेस करते हैं तो उस साइज़ की जाँच करें।

5
@ जो: समस्या इतनी नहीं है कि देशी सरणियों को तोड़ दिया जाए। यह है कि वे प्रतिस्थापित करना असंभव है। एक शुरुआत के लिए, vector::operator[]डिबग मोड में सीमा की जाँच करते हैं- कुछ देशी सरणियाँ नहीं कर सकते हैं- और दूसरी बात, सी में कोई रास्ता नहीं है जो मूल सरणी प्रकार को स्वैप कर सकता है जो सीमा जाँच कर सकता है, क्योंकि कोई टेम्पलेट नहीं है और कोई ऑपरेटर नहीं है अधिक भार। C ++ में, अगर आप से ले जाना चाहते T[]करने के लिए std::array, आप व्यावहारिक रूप से अभी बाहर एक typedef स्वैप कर सकते हैं। C में, इसे प्राप्त करने का कोई तरीका नहीं है, और समकक्ष कार्यक्षमता के साथ वर्ग लिखने का कोई तरीका नहीं है, अकेले इंटरफ़ेस दें।
20-16 बजे डेडएमजी

3
@ जो: सिवाय इसके कि यह कभी भी सांख्यिकीय रूप से नहीं हो सकता है, और आप इसे कभी भी सामान्य नहीं बना सकते हैं। यह जो एक ही भूमिका है कि सिद्ध सी में किसी भी पुस्तकालय लिखने के लिए असंभव है std::vector<T>और std::array<T, N>सी में क्या ++। किसी भी पुस्तकालय को डिजाइन करने और निर्दिष्ट करने का कोई तरीका नहीं होगा, यहां तक ​​कि एक मानक भी नहीं, जो ऐसा कर सके।
डेडएमजी

1
मुझे यकीन नहीं है कि आपका मतलब क्या है "यह कभी भी सांख्यिकीय रूप से नहीं हो सकता है।" जैसा कि मैंने उस शब्द का उपयोग किया है, std::vectorकभी भी सांख्यिकीय रूप से आकार नहीं ले सकता। जेनेरिक के लिए, आप इसे उतना ही जेनेरिक बना सकते हैं, जितना अच्छा C होना चाहिए - void * (add, remove, resize) और बाकी सब पर विशेष रूप से लिखे गए मूलभूत ऑपरेशनों की एक छोटी संख्या। यदि आप यह शिकायत करने जा रहे हैं कि C में C ++ शैली की जेनरिक नहीं है, तो वह सुरक्षित बफर हैंडलिंग के दायरे से बाहर है।

7

समस्या सी भाषा के साथ नहीं है ।

IMO, दूर करने के लिए एकमात्र बड़ी बाधा यह है कि C को केवल सादा ही बुरी तरह सिखाया जाता है । शुरुआत से ही प्रोग्रामरों की प्रत्येक नई पीढ़ी के दिमाग में जहर घोलने और गलत सूचनाओं के संदर्भों को संदर्भ नियमावली और व्याख्यान नोट्स में संस्थागत रूप दिया गया है। छात्रों को "आसान" I / O कार्यों का एक संक्षिप्त विवरण दिया जाता है जैसे gets1 या scanfफिर अपने स्वयं के उपकरणों पर छोड़ दिया जाता है। उन्हें यह नहीं बताया गया है कि वे उपकरण कहाँ या कैसे विफल हो सकते हैं, या उन विफलताओं को कैसे रोका जा सकता है। उन्हें उपयोग करने के बारे में नहीं बताया गया है fgetsऔरstrtol/strtodक्योंकि उन्हें "उन्नत" उपकरण माना जाता है। फिर वे पेशेवर दुनिया पर अपना कहर बरपाने ​​के लिए बेकरार हैं। ऐसा नहीं है कि कई अधिक अनुभवी प्रोग्रामर किसी भी बेहतर जानते हैं, क्योंकि उन्होंने एक ही मस्तिष्क-क्षतिग्रस्त शिक्षा प्राप्त की है। यह पागलपन है। मैं यहां ढेर सारे सवालों और स्टैक ओवरफ्लो पर और अन्य साइटों पर देख रहा हूं, जहां यह स्पष्ट है कि सवाल पूछने वाला व्यक्ति किसी ऐसे व्यक्ति द्वारा पढ़ाया जा रहा है जो बस यह नहीं जानता कि वे किस बारे में बात कर रहे हैं , और निश्चित रूप से आप बस नहीं कह सकते हैं "आपका प्रोफेसर गलत है," क्योंकि वह एक प्रोफेसर है और आप इंटरनेट पर सिर्फ कुछ लड़के हैं

और तब आपके पास वह भीड़ होती है जो किसी भी उत्तर की शुरुआत करने से वंचित रह जाती है, "ठीक है, भाषा के मानक के अनुसार ..." क्योंकि वे वास्तविक दुनिया में काम कर रहे हैं और उनके अनुसार मानक वास्तविक दुनिया पर लागू नहीं होते हैं । मैं किसी ऐसे व्यक्ति के साथ व्यवहार कर सकता हूं, जिसकी सिर्फ एक बुरी शिक्षा है, लेकिन जो कोई भी अज्ञानी होने का आग्रह करता है, वह उद्योग पर एक प्रहार है।

यदि सुरक्षित कोड लिखने पर जोर देने के साथ भाषा को सही ढंग से पढ़ाया जाता है तो कोई बफर अतिप्रवाह समस्या नहीं होगी । यह "कठिन" नहीं है, यह "उन्नत" नहीं है, यह सिर्फ सावधान रहना है।

हाँ, यह एक शेख़ी है।


1 जो, शुक्र है, आखिरकार भाषा के विनिर्देश से हटा दिया गया है, हालांकि यह 40 साल के विरासत कोड के लिए हमेशा के लिए दुबक जाएगा।


1
जबकि मैं ज्यादातर आपके साथ सहमत हूं, मुझे लगता है कि आप अभी भी थोड़ा अनुचित हैं। जिसे हम "सुरक्षित" मानते हैं, वह भी समय का एक कार्य है (और मुझे लगता है कि आप एक पेशेवर सॉफ़्टवेयर डेवलपर हैं जो मुझसे बहुत लंबे हैं, इसलिए मुझे यकीन है कि आप इससे परिचित हैं)। अब से दस साल बाद किसी ने इस बारे में बातचीत की होगी कि 2012 में हर किसी ने DoS- सक्षम हैश टेबल कार्यान्वयन का उपयोग क्यों किया, क्या हमें सुरक्षा के बारे में कुछ नहीं पता था? यदि शिक्षण में कोई समस्या है, तो यह एक समस्या है कि हम "सर्वश्रेष्ठ" अभ्यास को पढ़ाने पर ध्यान केंद्रित करते हैं, न कि उस सर्वोत्तम अभ्यास का विकास होता है।

1
और चलो ईमानदार हो। आप सिर्फ सुरक्षित कोड लिख सकते हैंsprintf , लेकिन इसका मतलब यह नहीं है कि भाषा त्रुटिपूर्ण नहीं थी। सी गया था त्रुटिपूर्ण और है त्रुटिपूर्ण - किसी भी भाषा की तरह है - और यह महत्वपूर्ण है कि हम उन खामियों को स्वीकार करते हैं तो हम उन्हें ठीक करने के लिए जारी कर सकते हैं।

@JoeWreschnig - जबकि मैं बड़े बिंदु से सहमत हूं, मुझे लगता है कि DoS- सक्षम हैश तालिका कार्यान्वयन और बफर ओवररन के बीच गुणात्मक अंतर है। पूर्व को आपके आसपास विकसित होने वाली परिस्थितियों के लिए जिम्मेदार ठहराया जा सकता है, लेकिन दूसरे के पास कोई बहाना नहीं है; बफर ओवररन कोडिंग त्रुटियां हैं, अवधि। हां, सी में कोई ब्लेड गार्ड नहीं है और अगर आप लापरवाह हैं तो आपको काट देगा; हम इस बात पर बहस कर सकते हैं कि भाषा में कोई दोष है या नहीं। यह इस तथ्य के लिए है कि जब वे भाषा सीख रहे होते हैं तो बहुत कम छात्रों को कोई सुरक्षा निर्देश दिया जाता है ।
जॉन बोडे

5

समस्या प्रोग्रामर अक्षमता की तुलना में प्रबंधकीय लघुदृष्टि की बहुत है। याद रखें, 90,000-लाइन वाले एप्लिकेशन को पूरी तरह से असुरक्षित होने के लिए केवल एक असुरक्षित ऑपरेशन की आवश्यकता होती है । यह लगभग संभावना के दायरे से परे है कि मौलिक रूप से असुरक्षित स्ट्रिंग हैंडलिंग के शीर्ष पर लिखा गया कोई भी आवेदन 100% सही होगा - जिसका अर्थ है कि यह असुरक्षित होगा।

समस्या यह है कि असुरक्षित होने की लागत या तो सही पते पर नहीं ली जाती है (ऐप को बेचने वाली कंपनी को लगभग कभी भी खरीद मूल्य वापस नहीं करना होगा), या उस समय स्पष्ट रूप से दिखाई नहीं देते हैं जब निर्णय किए जाते हैं ("हमें जहाज करना होगा" मार्च में कोई फर्क नहीं पड़ता! ")। मुझे पूरा यकीन है कि यदि आपने अपनी कंपनी के लाभ के बजाय अपने उपयोगकर्ताओं को दीर्घकालिक लागत और लागतें बताई हैं, तो सी या संबंधित भाषाओं में लिखना कहीं अधिक महंगा होगा, शायद इतना महंगा कि यह स्पष्ट रूप से कई में गलत विकल्प है खेतों जहां आजकल पारंपरिक ज्ञान कहता है कि यह एक आवश्यकता है। लेकिन यह तब तक नहीं बदलेगा जब तक कि बहुत सख्त सॉफ्टवेयर देयता पेश नहीं की जाती - जो उद्योग में कोई नहीं चाहता।


-1: सभी बुराई की जड़ के रूप में प्रबंधन को दोष देना विशेष रूप से रचनात्मक नहीं है। इतिहास को थोड़ा कम अनदेखा करना। जवाब लगभग अंतिम वाक्य द्वारा भुनाया जाता है।
मटनज

सुरक्षा में रुचि रखने वाले और इसके लिए भुगतान करने के इच्छुक उपयोगकर्ताओं द्वारा कड़ी सॉफ्टवेयर देयता पेश की जा सकती है। यकीनन, सुरक्षा उल्लंघनों के लिए कठोर दंड देकर इसे पेश किया जा सकता है। यदि उपयोगकर्ता सुरक्षा के लिए भुगतान करने के लिए तैयार होंगे तो बाजार आधारित समाधान काम करेगा, लेकिन वे नहीं हैं।
डेविड थॉर्नले

4

C का उपयोग करने की एक महान शक्ति यह है कि यह आपको जिस भी तरह से फिट दिखाई देता है, उसमें मेमोरी को हेरफेर करने देता है।

C का उपयोग करने की एक बड़ी कमजोरी यह है कि यह आपको किसी भी तरह से मेमोरी को हेरफेर करने की सुविधा देता है।

किसी भी असुरक्षित कार्यों के सुरक्षित संस्करण हैं। हालांकि, प्रोग्रामर और कंपाइलर उनके उपयोग को सख्ती से लागू नहीं करते हैं।


2

C के निर्माता पुस्तकालयों को फिर से लागू करके इन मुद्दों को ठीक क्यों नहीं करते हैं?

संभवतः क्योंकि C ++ ने पहले ही ऐसा कर लिया था, और C कोड के साथ पिछड़ा संगत है। इसलिए यदि आप अपने C कोड में एक सुरक्षित स्ट्रिंग प्रकार चाहते हैं, तो आप बस st :: string का उपयोग करें और C ++ कंपाइलर का उपयोग करके अपना C कोड लिखें।

अंतर्निहित मेमोरी सबसिस्टम गार्ड ब्लॉक और उनकी वैधता की जाँच शुरू करके बफर ओवरफ्लो को रोकने में मदद कर सकता है - इसलिए सभी आवंटन में 'फ़िफ़िफ़े' के 4 बाइट्स जोड़े गए हैं, जब इन ब्लॉकों को लिखा जाता है, तो सिस्टम एक वाइबलर फेंक सकता है। इसकी मेमोरी मेमोरी को रोकने की गारंटी नहीं है, लेकिन यह दिखाएगा कि कुछ गलत हो गया है और इसे ठीक करने की आवश्यकता है।

मुझे लगता है कि समस्या यह है कि पुराने स्ट्रैची आदि रूटीन अभी भी मौजूद हैं। अगर उन्हें अकड़ आदि के पक्ष में हटा दिया गया तो इससे मदद मिलेगी।


1
स्ट्रैची आदि को पूरी तरह से हटाने से वृद्धिशील उन्नयन पथ और भी मुश्किल हो जाएगा, जिसके परिणामस्वरूप लोगों को बिल्कुल भी अपग्रेड नहीं करना होगा। जिस तरह से यह किया गया है अब आप C11 कंपाइलर पर स्विच कर सकते हैं, फिर _s वेरिएंट का उपयोग शुरू कर सकते हैं, फिर गैर-_ वेरिएंट पर प्रतिबंध लगा सकते हैं, फिर मौजूदा उपयोग को ठीक कर सकते हैं, जो भी समय व्यावहारिक रूप से व्यवहार्य है।

-2

यह समझना आसान है कि अतिप्रवाह समस्या क्यों तय नहीं है। C एक दो क्षेत्रों में त्रुटिपूर्ण था। उस समय उन खामियों को सहनीय या एक विशेषता के रूप में भी देखा जाता था। अब दशकों बाद उन खामियों को ठीक नहीं किया जा सकता है।

प्रोग्रामिंग समुदाय के कुछ हिस्से नहीं चाहते कि उन छेदों को प्लग किया जाए। जरा गौर से देखिए, तमाम तरह की जंगें जो शुरू होती हैं तार, एरे, पॉइंटर्स, गारबेज कलेक्शन ...


5
योग्य, भयानक और गलत तरीके से जवाब देने वाला।
हीथ हुननिकट

1
यह गलत उत्तर क्यों है, इस पर खुलासा करने के लिए: C में वास्तव में कई खामियां हैं, लेकिन बफर ओवरफ्लो आदि की अनुमति उनके साथ बहुत कम है, लेकिन मूल भाषा आवश्यकताओं के साथ। सी की नौकरी करने के लिए भाषा डिजाइन करना और बफर ओवरफ्लो की अनुमति नहीं देना संभव नहीं होगा। समुदाय के अंग क्षमताओं को छोड़ना नहीं चाहते हैं सी उन्हें अनुमति देता है, अक्सर अच्छे कारण के साथ। इन समस्याओं में से कुछ से बचने के तरीके के रूप में असहमति भी है, यह दिखाते हुए कि हमें प्रोग्रामिंग भाषा डिजाइन की पूरी समझ नहीं है, इससे ज्यादा कुछ नहीं।
डेविड थॉर्नले

1
@DavidThornley: कोई व्यक्ति C की नौकरी करने के लिए एक भाषा डिज़ाइन कर सकता है, लेकिन ऐसा कर सकता है कि चीजों को करने के सामान्य मुहावरेदार तरीके कम से कम एक बफर को अत्यधिक कुशलता से बफर की जांच करने की अनुमति दें , तो कंपाइलर को ऐसा करने का चयन करना चाहिए। memcpy()उपलब्ध होने और इसे सरणी सेगमेंट को कुशलता से कॉपी करने के केवल मानक साधन होने के बीच एक बड़ा अंतर है ।
सुपरकैट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.