2009-05-15 22 views
55

मैं यह जानना चाहता हूं कि क्यों strncpy असुरक्षित माना जाता है। क्या किसी के पास इस पर किसी भी प्रकार का दस्तावेज है या इसका उपयोग करके शोषण के उदाहरण हैं?strncpy असुरक्षित क्यों है?

+4

यह मेरी समझ यह थी कि strcpy असुरक्षित था और कहा कि strncpy कि के सुरक्षित संस्करण था देख सकते हैं। –

+26

हालांकि नाम पर कोई _s नहीं है। _s के बिना सुरक्षित नहीं हो सकता है ... – Shog9

+2

यदि आप C++ का उपयोग कर रहे हैं, तो बस इसका उपयोग न करें और std :: string का उपयोग न करें। – lothar

उत्तर

35

this site पर एक नज़र डालें; यह एक काफी विस्तृत स्पष्टीकरण है। असल में, strncpy() को एनयूएल समाप्ति की आवश्यकता नहीं है, और इसलिए विभिन्न प्रकार के शोषण के लिए अतिसंवेदनशील है।

+1

अच्छा बिंदु। तो, यहां तक ​​कि strncpy के साथ, सुनिश्चित करें कि बफर एक '\ 0' के साथ समाप्त होता है। – rampion

+13

+1, लेकिन यह ध्यान रखना अच्छा है कि जब आप मैन्युअल रूप से नल टर्मिनेटर को भूलना भूल जाते हैं तो स्ट्रैस्पी केवल असुरक्षित होती है। यदि आपको याद रखने में परेशानी हो रही है, तो एक रैपर फ़ंक्शन पर विचार करें, जो हमेशा अंतिम अक्षर को strncpy कॉल करने के बाद '\ 0' पर सेट करता है। – ojrac

+0

@ojrac, मुझे लगता है कि रैपर को कम से कम माइक्रोसॉफ्ट के रनटाइम के उपयोगकर्ताओं के लिए strncpy_s() नाम दिया गया है। विस्तृत चार उत्साही लोगों के लिए _wcsncpy_s() भी है। – RBerteig

6

स्ट्रैन्पी का सुरक्षित रूप से उपयोग करने के लिए, किसी को या तो (1) परिणाम बफर पर मैन्युअल रूप से एक शून्य चरित्र को चिपका देना चाहिए, (2) पता है कि बफर पहले से शून्य के साथ समाप्त होता है, और strncpy को पास (लंबाई -1), या (3) जानते हैं कि बफर को किसी भी विधि का उपयोग करके कॉपी नहीं किया जाएगा जो इसकी लंबाई को बफर लंबाई तक सीमित नहीं करेगा।

यह ध्यान रखना महत्वपूर्ण है कि strncpy प्रतिलिपि स्ट्रिंग के पीछे बफर में सबकुछ शून्य-भर देगा, जबकि अन्य लंबाई-सीमित स्ट्रैपी वेरिएंट नहीं होंगे। यह कुछ मामलों में एक प्रदर्शन नाली हो सकता है, लेकिन अन्य मामलों में एक सुरक्षा लाभ हो सकता है। उदाहरण के लिए, अगर किसी ने "supercalifragilisticexpalidocious" को एक बफर में कॉपी करने के लिए स्ट्रक्स्पी का उपयोग किया और फिर "इसे" कॉपी करने के लिए, बफर "it^ercalifragilisticexpalidocious ^" (शून्य बाइट का प्रतिनिधित्व करने के लिए "^" का उपयोग करके) रखेगा। यदि बफर को एक निश्चित आकार के प्रारूप में कॉपी किया जाता है, तो अतिरिक्त डेटा इसके साथ टैग कर सकता है।

11

मूल समस्या जाहिर है कि strcpy(3) एक memory-safe operation नहीं था, इसलिए एक हमलावर बफर जो स्टैक पर कोड को अधिलेखित कर देगा की तुलना में एक स्ट्रिंग लंबे समय तक आपूर्ति कर सकता है, और अगर ध्यान से व्यवस्था की, हमलावर से मनमाना कोड निष्पादित कर सकता है।

लेकिन strncpy(3) में एक और समस्या है कि यह गंतव्य पर हर मामले में शून्य समाप्ति की आपूर्ति नहीं करता है। (गंतव्य बफर से अधिक समय तक एक स्रोत स्ट्रिंग की कल्पना करें।) भविष्य के संचालन अपेक्षाकृत आकार के बफर और खराब होने के बीच सी नल-टर्मिनेटेड तारों को अनुरूप बनाने की अपेक्षा कर सकते हैं जब परिणाम अभी तक एक तिहाई बफर पर कॉपी किया गया हो।

strncpy (3) का उपयोग strcpy (3) से बेहतर है लेकिन strlcpy (3) जैसी चीजें अभी भी बेहतर हैं।

4

प्रश्न "लोड" आधार पर आधारित है, जो प्रश्न स्वयं को अमान्य बनाता है।

नीचे की रेखा यह है कि strncpy असुरक्षित नहीं माना जाता है और इसे कभी भी असुरक्षित नहीं माना जाता है। "असुरक्षा" का एकमात्र दावा उस समारोह से जुड़ा जा सकता है, सी मेमोरी मॉडल और सी भाषा की सामान्य असुरक्षा का व्यापक दावा है। (लेकिन यह स्पष्ट रूप से एक पूरी तरह से अलग विषय है)।

सी भाषा strncpy में निहित "असुरक्षा" के किसी तरह के गुमराह विश्वास "सुरक्षित स्ट्रिंग नकल के लिए" strncpy का उपयोग कर के व्यापक संदिग्ध पैटर्न से ली गई है, यानी कुछ इस समारोह नहीं करता है और कभी नहीं किया है के दायरे के भीतर के लिए इरादा किया गया है। इस तरह के उपयोग वास्तव में अत्यधिक त्रुटि प्रवण है। लेकिन अगर आप "अत्यधिक त्रुटि प्रवण" और "असुरक्षित" के बीच समानता चिह्न डालते हैं, तो भी यह एक उपयोग समस्या है (यानी शिक्षा की कमी की कमी) strncpy समस्या नहीं है।

असल में, कोई कह सकता है कि strncpy के साथ एकमात्र समस्या दुर्भाग्यपूर्ण नामकरण है, जो नौसिखिया प्रोग्रामर मानते हैं कि वे समझते हैं कि यह फ़ंक्शन वास्तव में विनिर्देश पढ़ने के बजाय क्या करता है। फ़ंक्शन नाम को देखते हुए एक अक्षम प्रोग्रामर मानता है कि strncpystrcpy का "सुरक्षित संस्करण" है, जबकि वास्तव में ये दो कार्य पूरी तरह से असंबंधित हैं।

एक उदाहरण के लिए, डिवीजन ऑपरेटर के खिलाफ बिल्कुल वही दावा किया जा सकता है।जैसा कि आप में से ज्यादातर जानते हैं, सी भाषा के बारे में अक्सर पूछे जाने वाले प्रश्नों में से एक है "मुझे लगता है कि 1/2 का मूल्यांकन 0.5 पर होगा, लेकिन मुझे 0 इसके बजाय मिला।" फिर भी, हम दावा नहीं करते कि डिवीजन ऑपरेटर असुरक्षित है क्योंकि भाषा शुरुआती अपने व्यवहार को गलत तरीके से समझते हैं।

एक और उदाहरण के लिए, हम छद्म-यादृच्छिक संख्या जनरेटर फ़ंक्शंस को "असुरक्षित" नहीं कहते हैं क्योंकि अक्षम प्रोग्रामर अक्सर इस तथ्य से आश्चर्यचकित होते हैं कि उनका आउटपुट वास्तव में यादृच्छिक नहीं है।

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

माना जाता है कि डिवीजन ऑपरेटर के साथ चीजों को हल करने के लिए आमतौर पर strncpy के उद्देश्य को सीखने के लिए भाषा छात्र के लिए अधिक समय लगता है। हालांकि, यह strncpy के खिलाफ किसी भी "असुरक्षा" दावों का आधार है।

पीएस स्वीकृत उत्तर में जुड़े सीईआरटी दस्तावेज को बिल्कुल समर्पित किया गया है: strncpy के सामान्य अक्षम अक्षमता की असुरक्षा को प्रदर्शित करने के लिए strcpy के "सुरक्षित" संस्करण के रूप में कार्य करें। यह दावा करने के इरादे से किसी भी तरह से नहीं है कि strncpy स्वयं किसी भी तरह असुरक्षित है।

+2

जब लोग कहते हैं कि "strncpy' असुरक्षित है" उनका क्या मतलब है "इसमें [सफलता का गड्ढा नहीं है] (http://blogs.msdn.com/b/brada/archive/2003/10/02/ 50420.aspx)। " कौन सा सही है। –

0

सबसे खराब स्थिति तब होती है जब आपका स्रोत और गंतव्य बफर स्मृति एक दूसरे के ऊपर आती है। तो जब आप महसूस करते हैं कि आपके प्रोग्राम में अतिव्यापी स्थिति हो सकती है तो strncpy का उपयोग करने से बचें। Strncpy के बजाय आप ओवरलैपिंग परिदृश्य में memmove फ़ंक्शन का उपयोग कर सकते हैं।

नीचे मैं एक साधारण उदाहरण का वर्णन कर रहा हूं जो ओवरलैपिंग परिदृश्य में strncpy का वर्णन करता है।

#include <stdio.h> 
    #include <string.h> 
    int main() { 

    char aszMessage[10] ="12345"; //Source Buffer 
    short siLen=4; // Length of byte you want to copy 


    strncpy(aszMessage + 2,aszMessage+1,siLen);//Here memory overlap 

    printf("\n\n\tMessage = %s\n",aszMessage); 



    return 0; 
} 

यहाँ मैं स्वीकार करने कर रहा हूँ, उत्पादन 122,345 होना चाहिए लेकिन यहां उत्पादन 122,222 है, कि strncpy की सबसे बड़ी वापस आने परिदृश्य है।

इस समस्या को मेमोव फ़ंक्शन का उपयोग करके हल किया जा सकता है।

#include <stdio.h> 
#include <string.h> 
int main() { 

char aszMessage[10] ="12345"; //Source Buffer 
short siLen=4; // Length of byte you want to copy 


memmove(aszMessage + 2,aszMessage+1,siLen);//Here memory overlap 

printf("\n\n\tMessage = %s\n",aszMessage); 


return 0; 
} 

अब मैं इच्छा उत्पादन 122345.

हो रही है अधिक विस्तार के लिए आप इस लिंक http://aticleworld.com/how-to-use-strncpy-and-how-to-write-your-own-strncpy/

+1

भविष्य में रेड लेक्सस क्षमा करें, मैं इसे फिर से करने से बचूंगा। –