`strcpy` का इस्तेमाल भी प्रतिबंधित
(daniel.haxx.se)- cURL प्रोजेक्ट ने पहले
strncpy()को हटाने के बाद, अबstrcpy()को भी codebase में पूरी तरह प्रतिबंधित कर दिया है strcpy()का API सरल है, लेकिन इसमें buffer size validation अलग हो जाने का जोखिम रहता है, इसलिए लंबी अवधि के maintenance में यह सुरक्षित नहीं माना जाता- इसके बदले
curlx_strcopy()नाम का एक नया function जोड़ा गया है, जो destination buffer size और string length दोनों को argument के रूप में लेकर copy संभव है या नहीं, यह जांचने के बाद ही काम करता है - यह function अंदरूनी तौर पर
memcpy()का उपयोग करता है और null terminator को संभालने की गारंटी भी देता है - इस बदलाव से security और code consistency बेहतर होती है, और AI द्वारा गलत vulnerability reports बनाने की समस्या भी कम हो सकती है
strcpy हटाने की पृष्ठभूमि
- cURL पहले ही
strncpy()के सभी calls हटा चुका था, और इस function के कम सहज API, null termination की गारंटी न दे पाने, और अनावश्यक 0 padding जैसी समस्याओं की ओर इशारा किया था- जहां partial string copy की जरूरत होती है, वहां
memcpy()का उपयोग करके null termination को अलग से संभालने के लिए बदलाव किया गया
- जहां partial string copy की जरूरत होती है, वहां
strcpy()का API सरल है, लेकिन यह buffer size को स्पष्ट रूप से नहीं बताता, जिससे maintenance के दौरान validation code और copy call अलग हो जाने का जोखिम रहता है- जब code को दशकों तक कई developers बदलते रहते हैं, तब buffer size validation निष्प्रभावी हो जाने की संभावना बनी रहती है
नया string copy function पेश किया गया
- इस जोखिम को रोकने के लिए
curlx_strcopy()नाम का एक replacement function जोड़ा गया- यह destination buffer, buffer size, source buffer, और source string length को arguments के रूप में लेता है
- copy और null termination दोनों संभव होने पर ही
memcpy()से काम करता है - विफल होने पर destination buffer को empty string से initialize कर देता है
- इस function में
strcpy()की तुलना में ज्यादा arguments और ज्यादा code चाहिए, लेकिन buffer validation को copy operation के साथ मजबूती से जोड़कर सुरक्षा सुनिश्चित की जाती है - cURL codebase में
strcpy()के उपयोग को पूरी तरह प्रतिबंधित कर दिया गया है, ठीकstrncpy()की तरह
implementation details
- function definition का उदाहरण इस प्रकार है
void curlx_strcopy(char *dest, size_t dsize, const char *src, size_t slen) { DEBUGASSERT(slen < dsize); if(slen < dsize) { memcpy(dest, src, slen); dest[slen] = 0; } else if(dsize) dest[0] = 0; } DEBUGASSERTके जरिए development के दौरान errors को जल्दी पकड़ा जाता है, और actual deployment environment में इसे हमेशा सफल होने के हिसाब से design किया गया हैstrcpyकी तरह इसमें return value नहीं है, और testing तथा fuzzing चरण में errors पकड़ने का तरीका अपनाया गया है
community reaction
- कुछ developers ने कहा कि यह
strcpy_s()(C11 Annex K) जैसा है, लेकिन cURL अभी भी C89 standard का उपयोग कर रहा है - अन्य प्रतिक्रियाओं में return value जोड़ने की जरूरत या buffer failure के समय handling बेहतर करने के सुझाव भी आए
- इस पर cURL की ओर से कहा गया कि “यह function हमेशा सफल होने के लिए design किया गया है, इसलिए return value की जरूरत नहीं है”
AI से जुड़ा अतिरिक्त प्रभाव
- इस बदलाव से AI chatbots द्वारा cURL code में
strcpyके उपयोग को गलत तरीके से पहचानकर उसे ‘vulnerable’ बताने की समस्या रोकी जा सकती है - हालांकि, लेखक ने यह भी कहा कि “AI आगे भी दूसरी झूठी reports बना सकता है,” और AI-आधारित code analysis की सीमाओं का जिक्र किया
5 टिप्पणियां
strcpyकी जगहsnprintfइस्तेमाल करना सही है। अगर कोड मेंstrcpyहै, तो उसे बनाने वाले डेवलपर का पता लगाना चाहिए।यह तरीका मैंने 25 साल पहले, जब मैं एक गेम कंपनी में काम करता था, तब debug code के रूप में अपनाया था—और क्या सिर्फ
strcpyही समस्या थी? Release में speed बढ़ाने के लिए इन्हें फिर से खोलकर ही service की गई थी। दरअसल गेम इंडस्ट्री में memory collision सबसे संवेदनशील मुद्दों में से एक है, इसलिए काम भी बहुत सावधानी और पूरी सतर्कता से किया जाता था, यहाँ तक कि memory debugger भी हमने खुद बनाकर इस्तेमाल किया था। लेकिन आज पीछे मुड़कर देखता हूँ तो पता चलता है कि वही चीज़ दरअसल garbage collection बना रही थी। धुंधली-सी यादें हैं।त्रुटि C4996
'strcpy': यह function या variable असुरक्षित हो सकता है।strcpy_sका उपयोग करने पर विचार करें। deprecation को disable करने के लिए_CRT_SECURE_NO_WARNINGSका उपयोग करें। details के लिए online help देखें.Hacker News की राय
strcpy() सिर्फ security ही नहीं, performance के लिहाज़ से भी अच्छा नहीं है
पहले यह सोचा जाता था कि जब string की length पता न हो तो strcpy() efficient है, लेकिन असल में यह एक-एक byte copy करता है, इसलिए CPU को branch prediction करनी पड़ती है और यह inefficient है
C के string routines में लगभग सभी में बड़ी सीमाएँ हैं, इसलिए वे बेकार लगते हैं
इसलिए मुझे लगता है कि string pointer के साथ allocated memory size रिकॉर्ड करने वाली library ज़रूर चाहिए
उदाहरण के लिए bstring library देखी जा सकती है
char username[20]जैसे field को NUL से pad करने के लिए। संबंधित दस्तावेज़ के लिए string_copying.7 manual देखेंयह अजीब है कि curlx_strcopy success/failure return नहीं करता
dest[0] चेक किया जा सकता है, लेकिन यह error-prone है और intuitive भी नहीं
DEBUGASSERT(slen < dsize);pass हो जाए तो उसे success माना जा रहा है, लेकिन release build में assert हट सकता है। मुझे लगता है explicit error code बेहतर हैstrncpy() मूल रूप से null-terminated strings के लिए नहीं, बल्कि fixed-length fields के लिए था
समस्या तब शुरू हुई जब static analyzers ने strcpy की जगह strncpy इस्तेमाल करने की सलाह देनी शुरू की। असली alternatives snprintf या strlcpy थे
यह API कुछ Annex-K जैसा लगता है। Destination buffer size में NUL space शामिल है, लेकिन source size में नहीं
मुझे तो सीधा memcpy इस्तेमाल करना बेहतर लगता है
लेख में यह बात असरदार लगी कि “strcpy AI द्वारा बनाए गए गलत vulnerability reports के लिए चारा है”
“Code के पास check करो” वाला principle अच्छा है, लेकिन जब data के lifecycle की शुरुआत में ही validation करनी हो तो मामला धुंधला हो जाता है
Rust के Result type की तरह अगर type से ही यह अलग किया जा सके कि data “validated” है, तो अच्छा होगा
Buffer size और string length के बीच का off-by-one अंतर बहुत भयानक usability issue है। आगे भी इससे errors होने की संभावना है
नया प्रस्तावित string copy function, copy संभव न होने पर destination buffer को खाली कर देता है और void return करता है
लेकिन मुझे लगता है ऐसे मामलों को error की तरह handle करना चाहिए और buffer को छूना नहीं चाहिए। सिर्फ DEBUGASSERT पर निर्भर रहना असुरक्षित लगता है
project पूरा होने पर बधाई। C/C++ में भी कोशिश की जाए तो memory safety हासिल की जा सकती है
लेकिन mobile environment में graph font size बहुत छोटा है, इसलिए readability गिर जाती है
पूरी तरह C3 भाषा पर जाना भी अच्छा है। यह ऐसा प्रोजेक्ट है जो C भाषा के syntax में न्यूनतम बदलाव रखकर आधुनिक सुविधाएँ जोड़ता है, इसलिए migration भी आसान है।