एक 65-बाइट की मॉडल फ़ाइल लोकप्रिय Llama CPP इन्फरेंस इंजन को अचानक रोक सकती है। यह छोटा सा पेलोड पार्सर के भीतर division-by-zero को ट्रिगर करता है, जिससे SIGFPE क्रैश हो जाता है।
यह क्रैश क्यों महत्वपूर्ण है
क्या गलत हुआ
पार्सर मॉडल मेटाडेटा को C++ स्ट्रक्चर्स में पढ़ता है और यह जाँचता है कि प्रत्येक टेंसर डाइमेंशन (tensor dimension) "non-negative" (गैर-ऋणात्मक) है या नहीं। शून्य (zero) उस शर्त को पूरा करता है, इसलिए जाँच सफल हो जाती है। कोड की अगली लाइन फिर उस डाइमेंशन का उपयोग एक गणना में भाजक (divisor) के रूप में करती है, जो यह मानकर चलती है कि मान धनात्मक (positive) है। जब डाइमेंशन शून्य होता है, तो विभाजन एक फ्लोटिंग-पॉइंट एक्सेप्शन (SIGFPE) उत्पन्न करता है और प्रोग्राम को समाप्त कर देता है।
यह वैलिडेशन आवश्यक इनवेरिएंट (invariant) के केवल आधे हिस्से को कवर करता था: इसने ऋणात्मक मानों को तो रोक दिया लेकिन शून्य को नज़रअंदाज़ कर दिया, जो बाद की अंकगणितीय गणनाओं के लिए उतना ही असुरक्षित है।
डेवलपर्स को क्या करना चाहिए
- मॉडल फ़ाइलों को बाइनरी की तरह समझें। मॉडल लोड करने पर रॉ बाइट्स (raw bytes) को मेमोरी स्ट्रक्चर्स में पार्स किया जाता है, जो एक क्लासिक बाउंड्री है जहाँ अनचेक्ड डेटा प्रोसेस को क्रैश कर सकता है या उससे भी बुरा कर सकता है।
- आंशिक जाँच (partial checks) से बचें। ऐसी स्थिति जो आवश्यक इनवेरिएंट के केवल एक हिस्से को कवर करती है, सुरक्षा का झूठा अहसास देती है। यहाँ, "non-negative" अपर्याप्त था; कोड को "positive" की आवश्यकता थी।
- प्रत्येक जाँच के बाद धारणाओं पर सवाल उठाएं। जब कोई बाउंड्स टेस्ट (bounds test) दिखाई दे, तो सत्यापित करें कि उसके बाद वाला कोड किसी अधिक सख्त प्रॉपर्टी (stricter property) पर निर्भर न हो।
- फ़ज़िंग टूल्स (fuzzing tools) का उपयोग करें। लेखक ने libFuzzer को AddressSanitizer के साथ चलाकर इस बग का पता लगाया, जो इनपुट्स को बदलता (mutate) है और division by zero जैसे अवैध ऑपरेशन्स को फ्लैग करता है।
फिक्स (fix) कैसे लागू किया गया
फिक्स एक गार्ड (guard) जोड़ता है जो डाइमेंशन शून्य होने पर ओवरफ्लो गणना को छोड़ देता है। यह छोटा सा कंडीशनल (conditional) वैध शून्य-आकार के टेंसरों—जिनका उपयोग कुछ मॉडल वेरिएंट में वैकल्पिक सुविधाओं के लिए किया जाता है—के लिए सपोर्ट बनाए रखता है, जबकि क्रैश होने वाले रास्ते को खत्म कर देता है।
निष्कर्ष (Takeaway): एक अकेली 65-बाइट की फ़ाइल व्यापक रूप से तैनात इन्फरेंस इंजन को बंद कर सकती है; गहन वैलिडेशन और व्यवस्थित फ़ज़िंग मॉडल लोडर्स को सुरक्षित रखते हैं।
स्रोत: https://dev.to/harrisonsec/your-model-file-is-untrusted-input-1eap
