कंट्रोल फ़्लो इंटिग्रिटी (सीएफ़आई) एक सुरक्षा सुविधा है. यह कंपाइल की गई बाइनरी के ओरिजनल कंट्रोल फ़्लो ग्राफ़ में बदलाव करने की अनुमति नहीं देती. इससे इस तरह के हमलों को अंजाम देना काफ़ी मुश्किल हो जाता है.
Android 9 से, कर्नल में सीएफ़आई को चालू किया जा सकता है.
Linux कर्नल में, CFI के दो अलग-अलग इंप्लीमेंटेशन हैं:
- Linux 6.0 और इससे पहले के वर्शन के लिए, Clang CFI. यह Clang LTO पर निर्भर करता है
- Linux 6.1 और इसके बाद के वर्शन के लिए, Clang KCFI
Clang CFI के लिए, लिंक टाइम ऑप्टिमाइज़ेशन (एलटीओ) का इस्तेमाल करके कंपाइल करना ज़रूरी है. एलटीओ, ऑब्जेक्ट फ़ाइलों के LLVM बिटकोड को लिंक टाइम तक सेव रखता है. इससे कंपाइलर को यह बेहतर तरीके से पता चलता है कि कौनसे ऑप्टिमाइज़ेशन किए जा सकते हैं. Android पर टेस्टिंग के दौरान, LTO और CFI के कॉम्बिनेशन से कोड साइज़ और परफ़ॉर्मेंस पर बहुत कम असर पड़ा. हालांकि, LTO को चालू करने से कर्नल को बनाने में लगने वाला समय काफ़ी बढ़ जाता है.
Clang KCFI के लिए एलटीओ की ज़रूरत नहीं होती. इसलिए, Android के नए कर्नल को एलटीओ के बिल्ड-टाइम ओवरहेड के बिना, सीएफ़आई का फ़ायदा मिलता है.
लागू करना
CFI को CONFIG_CFI_CLANG विकल्प से कंट्रोल किया जाता है. इससे Clang CFI या Clang KCFI में से किसी एक को चालू किया जा सकता है.
सीएफ़आई और फ़ॉरवर्ड-कंट्रोल की अन्य जांचों को कैसे हैंडल किया जाता है, इस बारे में ज़्यादा तकनीकी जानकारी के लिए, LLVM डिज़ाइन का दस्तावेज़ देखें. KCFI को वहाँ -fsanitize=kcfi के तौर पर दिखाया गया है.
समस्या का हल
चालू करने के बाद, टाइप मैच न होने की किसी भी गड़बड़ी को ठीक करें. किसी ऐसे फ़ंक्शन पॉइंटर के ज़रिए इनडायरेक्ट फ़ंक्शन कॉल करने पर सीएफ़आई ट्रिप हो जाता है जो काम नहीं करता. जब CFI फ़ेल होने का पता चलता है, तो कर्नल एक चेतावनी प्रिंट करता है. इसमें कॉल किए गए फ़ंक्शन और फ़ेल होने की वजह बताने वाला स्टैकट्रेस, दोनों शामिल होते हैं. इसे ठीक करने के लिए, पक्का करें कि फ़ंक्शन पॉइंटर का टाइप हमेशा उस फ़ंक्शन के टाइप के जैसा हो जिसे कॉल किया गया है.
सीएफ़आई से जुड़ी गड़बड़ियों को ठीक करने के लिए, CONFIG_CFI_PERMISSIVE को चालू करें. इससे कर्नल पैनिक होने के बजाय, चेतावनी प्रिंट होती है. प्रोडक्शन में, अनुमति वाले मोड का इस्तेमाल नहीं किया जाना चाहिए.
सत्यापन
फ़िलहाल, CFI के लिए कोई खास सीटीएस टेस्ट उपलब्ध नहीं है. इसके बजाय, यह पक्का करें कि सीएफ़आई की सुविधा चालू होने और बंद होने पर, सीटीएस टेस्ट पास हो जाएं. इससे यह पुष्टि की जा सकेगी कि सीएफ़आई की सुविधा से डिवाइस पर कोई असर नहीं पड़ रहा है.