नियंत्रण प्रवाह अखंडता

2016 तक, एंड्रॉइड पर सभी कमजोरियों में से लगभग 86% मेमोरी सुरक्षा से संबंधित हैं। अधिकांश कमजोरियों का फायदा हमलावरों द्वारा किसी एप्लिकेशन के सामान्य नियंत्रण प्रवाह को बदलकर शोषण किए गए एप्लिकेशन के सभी विशेषाधिकारों के साथ मनमाने ढंग से दुर्भावनापूर्ण गतिविधियां करने के लिए किया जाता है। नियंत्रण प्रवाह अखंडता (सीएफआई) एक सुरक्षा तंत्र है जो संकलित बाइनरी के मूल नियंत्रण प्रवाह ग्राफ में परिवर्तन की अनुमति नहीं देता है, जिससे ऐसे हमलों को निष्पादित करना काफी कठिन हो जाता है।

एंड्रॉइड 8.1 में, हमने मीडिया स्टैक में एलएलवीएम के सीएफआई के कार्यान्वयन को सक्षम किया। एंड्रॉइड 9 में, हमने सीएफआई को अधिक घटकों और कर्नेल में भी सक्षम किया है। सिस्टम सीएफआई डिफ़ॉल्ट रूप से चालू है लेकिन आपको कर्नेल सीएफआई को सक्षम करने की आवश्यकता है।

एलएलवीएम के सीएफआई को लिंक-टाइम ऑप्टिमाइज़ेशन (एलटीओ) के साथ संकलन की आवश्यकता है। एलटीओ लिंक-टाइम तक ऑब्जेक्ट फ़ाइलों के एलएलवीएम बिटकोड प्रतिनिधित्व को संरक्षित करता है, जो कंपाइलर को बेहतर कारण बताने की अनुमति देता है कि कौन से अनुकूलन किए जा सकते हैं। एलटीओ को सक्षम करने से अंतिम बाइनरी का आकार कम हो जाता है और प्रदर्शन में सुधार होता है, लेकिन संकलन समय बढ़ जाता है। एंड्रॉइड पर परीक्षण में, एलटीओ और सीएफआई के संयोजन से कोड आकार और प्रदर्शन पर नगण्य ओवरहेड होता है; कुछ मामलों में दोनों में सुधार हुआ।

सीएफआई के बारे में अधिक तकनीकी विवरण और अन्य फॉरवर्ड-कंट्रोल जांचों को कैसे प्रबंधित किया जाता है, इसके लिए एलएलवीएम डिज़ाइन दस्तावेज़ देखें।

उदाहरण और स्रोत

सीएफआई कंपाइलर द्वारा प्रदान किया जाता है और कंपाइल समय के दौरान बाइनरी में इंस्ट्रूमेंटेशन जोड़ता है। हम क्लैंग टूलचेन में सीएफआई और एओएसपी में एंड्रॉइड बिल्ड सिस्टम का समर्थन करते हैं।

/platform/build/target/product/cfi-common.mk में घटकों के सेट के लिए Arm64 उपकरणों के लिए CFI डिफ़ॉल्ट रूप से सक्षम है। यह सीधे मीडिया घटकों के मेकफ़ाइल्स/ब्लूप्रिंट फ़ाइलों के सेट में भी सक्षम है, जैसे /platform/frameworks/av/media/libmedia/Android.bp और /platform/frameworks/av/cmds/stagefright/Android.mk

सीएफआई प्रणाली का कार्यान्वयन

यदि आप क्लैंग और एंड्रॉइड बिल्ड सिस्टम का उपयोग करते हैं तो सीएफआई डिफ़ॉल्ट रूप से सक्षम है। चूँकि CFI Android उपयोगकर्ताओं को सुरक्षित रखने में मदद करता है, इसलिए आपको इसे अक्षम नहीं करना चाहिए।

वास्तव में, हम आपको अतिरिक्त घटकों के लिए सीएफआई सक्षम करने के लिए दृढ़ता से प्रोत्साहित करते हैं। आदर्श उम्मीदवार विशेषाधिकार प्राप्त मूल कोड, या मूल कोड होते हैं जो अविश्वसनीय उपयोगकर्ता इनपुट को संसाधित करते हैं। यदि आप क्लैंग और एंड्रॉइड बिल्ड सिस्टम का उपयोग कर रहे हैं, तो आप अपनी मेकफ़ाइल्स या ब्लूप्रिंट फ़ाइलों में कुछ पंक्तियाँ जोड़कर नए घटकों में सीएफआई को सक्षम कर सकते हैं।

मेकफ़ाइल्स में सीएफआई का समर्थन करना

किसी मेक फ़ाइल में CFI को सक्षम करने के लिए, जैसे कि /platform/frameworks/av/cmds/stagefright/Android.mk , जोड़ें:

LOCAL_SANITIZE := cfi
# Optional features
LOCAL_SANITIZE_DIAG := cfi
LOCAL_SANITIZE_BLACKLIST := cfi_blacklist.txt
  • LOCAL_SANITIZE निर्माण के दौरान CFI को सैनिटाइज़र के रूप में निर्दिष्ट करता है।
  • LOCAL_SANITIZE_DIAG CFI के लिए डायग्नोस्टिक मोड चालू करता है। डायग्नोस्टिक मोड क्रैश के दौरान लॉगकैट में अतिरिक्त डिबग जानकारी प्रिंट करता है, जो आपके बिल्ड को विकसित और परीक्षण करते समय उपयोगी होता है। हालाँकि, प्रोडक्शन बिल्ड पर डायग्नोस्टिक मोड को हटाना सुनिश्चित करें।
  • LOCAL_SANITIZE_BLACKLIST घटकों को व्यक्तिगत कार्यों या स्रोत फ़ाइलों के लिए CFI इंस्ट्रूमेंटेशन को चुनिंदा रूप से अक्षम करने की अनुमति देता है। आप किसी भी उपयोगकर्ता-सामना वाली समस्या को ठीक करने के लिए अंतिम उपाय के रूप में ब्लैकलिस्ट का उपयोग कर सकते हैं जो अन्यथा मौजूद हो सकती है। अधिक विवरण के लिए, CFI को अक्षम करना देखें।

ब्लूप्रिंट फ़ाइलों में सीएफआई का समर्थन करना

किसी ब्लूप्रिंट फ़ाइल, जैसे /platform/frameworks/av/media/libmedia/Android.bp में CFI को सक्षम करने के लिए, जोड़ें:

   sanitize: {
        cfi: true,
        diag: {
            cfi: true,
        },
        blacklist: "cfi_blacklist.txt",
    },

समस्या निवारण

यदि आप नए घटकों में सीएफआई सक्षम कर रहे हैं, तो आपको फ़ंक्शन प्रकार बेमेल त्रुटियों और असेंबली कोड प्रकार बेमेल त्रुटियों के साथ कुछ समस्याओं का सामना करना पड़ सकता है।

फ़ंक्शन प्रकार बेमेल त्रुटियाँ इसलिए होती हैं क्योंकि CFI अप्रत्यक्ष कॉल को केवल उन फ़ंक्शंस पर जाने के लिए प्रतिबंधित करता है जिनका गतिशील प्रकार कॉल में उपयोग किए गए स्थिर प्रकार के समान होता है। सीएफआई वर्चुअल और गैर-वर्चुअल सदस्य फ़ंक्शन कॉल को केवल उन ऑब्जेक्ट्स पर जाने के लिए प्रतिबंधित करता है जो कॉल करने के लिए उपयोग किए जाने वाले ऑब्जेक्ट के स्थिर प्रकार का व्युत्पन्न वर्ग हैं। इसका मतलब है, जब आपके पास ऐसा कोड होता है जो इनमें से किसी भी धारणा का उल्लंघन करता है, तो सीएफआई द्वारा जोड़ा गया उपकरण निरस्त हो जाएगा। उदाहरण के लिए, स्टैक ट्रेस एक SIGABRT दिखाता है और लॉगकैट में एक बेमेल खोजने के लिए नियंत्रण प्रवाह अखंडता के बारे में एक पंक्ति होती है।

इसे ठीक करने के लिए, सुनिश्चित करें कि कॉल किए गए फ़ंक्शन का प्रकार वही है जो स्थिर रूप से घोषित किया गया था। यहां दो उदाहरण सीएल हैं:

एक अन्य संभावित समस्या सीएफआई को उस कोड में सक्षम करने का प्रयास करना है जिसमें असेंबली के लिए अप्रत्यक्ष कॉल शामिल हैं। चूँकि असेंबली कोड टाइप नहीं किया गया है, इसके परिणामस्वरूप प्रकार बेमेल हो जाता है।

इसे ठीक करने के लिए, प्रत्येक असेंबली कॉल के लिए मूल कोड रैपर बनाएं, और रैपर्स को कॉलिंग पॉइंटर के समान फ़ंक्शन हस्ताक्षर दें। इसके बाद रैपर सीधे असेंबली कोड को कॉल कर सकता है। चूँकि प्रत्यक्ष शाखाएँ CFI द्वारा इंस्ट्रुमेंट नहीं की जाती हैं (उन्हें रनटाइम पर पुनः निर्देशित नहीं किया जा सकता है और इसलिए सुरक्षा जोखिम पैदा नहीं होता है), इससे समस्या ठीक हो जाएगी।

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

सीएफआई को अक्षम करना

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

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

मान्यकरण

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