SELinux का कार्यान्वयन

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

मुख्य फ़ाइलें

SELinux को सक्षम करने के लिए, नवीनतम Android कर्नेल को एकीकृत करें और फिर सिस्टम/सेपॉलिसी निर्देशिका में पाई गई फ़ाइलों को शामिल करें। संकलित होने पर, उन फ़ाइलों में SELinux कर्नेल सुरक्षा नीति शामिल होती है और अपस्ट्रीम एंड्रॉइड ऑपरेटिंग सिस्टम को कवर करती है।

सामान्य तौर पर, आपको system/sepolicy फ़ाइलों को सीधे संशोधित नहीं करना चाहिए। इसके बजाय, /device/ manufacturer / device-name /sepolicy निर्देशिका में अपनी डिवाइस-विशिष्ट नीति फ़ाइलें जोड़ें या संपादित करें। एंड्रॉइड 8.0 और उच्चतर में, इन फ़ाइलों में आपके द्वारा किए गए परिवर्तन केवल आपकी विक्रेता निर्देशिका में नीति को प्रभावित करना चाहिए। एंड्रॉइड 8.0 और उच्चतर में सार्वजनिक सेपॉलिसी को अलग करने के बारे में अधिक जानकारी के लिए, एंड्रॉइड 8.0+ में सेपॉलिसी को अनुकूलित करना देखें। Android संस्करण के बावजूद, आप अभी भी इन फ़ाइलों को संशोधित कर रहे हैं:

नीति फ़ाइलें

*.te पर समाप्त होने वाली फ़ाइलें SELinux नीति स्रोत फ़ाइलें हैं, जो डोमेन और उनके लेबल को परिभाषित करती हैं। आपको /device/ manufacturer / device-name /sepolicy में नई नीति फ़ाइलें बनाने की आवश्यकता हो सकती है, लेकिन जहां संभव हो आपको मौजूदा फ़ाइलों को अपडेट करने का प्रयास करना चाहिए।

प्रसंग फ़ाइलें

संदर्भ फ़ाइलें वह जगह हैं जहां आप अपनी वस्तुओं के लिए लेबल निर्दिष्ट करते हैं।

  • file_contexts फ़ाइलों को लेबल निर्दिष्ट करता है और विभिन्न उपयोगकर्तास्पेस घटकों द्वारा उपयोग किया जाता है। जैसे ही आप नई नीतियां बनाते हैं, फ़ाइलों को नए लेबल निर्दिष्ट करने के लिए इस फ़ाइल को बनाएं या अपडेट करें। नई file_contexts लागू करने के लिए, फ़ाइल सिस्टम छवि को फिर से बनाएँ या पुनः लेबल की जाने वाली फ़ाइल पर restorecon चलाएँ। अपग्रेड करने पर, अपग्रेड के हिस्से के रूप में file_contexts में परिवर्तन स्वचालित रूप से सिस्टम और उपयोगकर्ताडेटा विभाजन पर लागू होते हैं। आपके init में restorecon_recursive कॉल जोड़कर अन्य विभाजनों में अपग्रेड करने पर परिवर्तन स्वचालित रूप से लागू किए जा सकते हैं। विभाजन के बाद board .rc फ़ाइल को पढ़ने-लिखने के लिए माउंट किया गया है।
  • genfs_contexts फ़ाइल सिस्टम को लेबल निर्दिष्ट करता है, जैसे कि proc या vfat जो विस्तारित विशेषताओं का समर्थन नहीं करते हैं। यह कॉन्फ़िगरेशन कर्नेल नीति के भाग के रूप में लोड किया गया है, लेकिन परिवर्तन इन-कोर इनोड के लिए प्रभावी नहीं हो सकते हैं, परिवर्तन को पूरी तरह से लागू करने के लिए फ़ाइल सिस्टम को रीबूट या अनमाउंट करने और फिर से माउंट करने की आवश्यकता होती है। विशिष्ट लेबल को विशिष्ट माउंट के लिए भी निर्दिष्ट किया जा सकता है, जैसे कि context=mount विकल्प का उपयोग करके vfat
  • property_contexts एंड्रॉइड सिस्टम गुणों को लेबल निर्दिष्ट करता है ताकि यह नियंत्रित किया जा सके कि कौन सी प्रक्रियाएं उन्हें सेट कर सकती हैं। यह कॉन्फ़िगरेशन स्टार्टअप के दौरान init प्रक्रिया द्वारा पढ़ा जाता है।
  • service_contexts एंड्रॉइड बाइंडर सेवाओं को लेबल प्रदान करता है ताकि यह नियंत्रित किया जा सके कि कौन सी प्रक्रियाएं सेवा के लिए बाइंडर संदर्भ जोड़ सकती हैं (रजिस्टर कर सकती हैं) और ढूंढ सकती हैं (लुकअप कर सकती हैं)। यह कॉन्फ़िगरेशन स्टार्टअप के दौरान servicemanager प्रक्रिया द्वारा पढ़ा जाता है।
  • seapp_contexts ऐप प्रक्रियाओं और /data/data निर्देशिकाओं को लेबल निर्दिष्ट करता है। यह कॉन्फ़िगरेशन प्रत्येक ऐप लॉन्च पर zygote प्रक्रिया द्वारा और स्टार्टअप के दौरान installd द्वारा पढ़ा जाता है।
  • mac_permissions.xml ऐप्स को उनके हस्ताक्षर और वैकल्पिक रूप से उनके पैकेज नाम के आधार पर एक seinfo टैग प्रदान करता है। seinfo टैग को उस seinfo टैग वाले सभी ऐप्स को एक विशिष्ट लेबल निर्दिष्ट करने के लिए seapp_contexts फ़ाइल में एक कुंजी के रूप में उपयोग किया जा सकता है। यह कॉन्फ़िगरेशन स्टार्टअप के दौरान system_server द्वारा पढ़ा जाता है।
  • keystore2_key_contexts Keystore 2.0 नेमस्पेस को लेबल निर्दिष्ट करता है। ये नेमस्पेस keystore2 डेमॉन द्वारा लागू किए गए हैं। कीस्टोर ने हमेशा यूआईडी/एआईडी आधारित नेमस्पेस प्रदान किया है। कीस्टोर 2.0 अतिरिक्त रूप से सेपॉलिसी परिभाषित नेमस्पेस को लागू करता है। इस फ़ाइल के प्रारूप और परंपराओं का विस्तृत विवरण यहां पाया जा सकता है।

बोर्डकॉन्फ़िग.एमके मेकफ़ाइल

नीति और संदर्भ फ़ाइलों को संपादित करने या जोड़ने के बाद, sepolicy उपनिर्देशिका और प्रत्येक नई नीति फ़ाइल को संदर्भित करने के लिए अपने /device/ manufacturer / device-name /BoardConfig.mk मेकफ़ाइल को अपडेट करें। BOARD_SEPOLICY वेरिएबल्स के बारे में अधिक जानकारी के लिए, system/sepolicy/README फ़ाइल देखें।

BOARD_SEPOLICY_DIRS += \
        <root>/device/manufacturer/device-name/sepolicy

BOARD_SEPOLICY_UNION += \
        genfs_contexts \
        file_contexts \
        sepolicy.te

पुनर्निर्माण के बाद, आपका डिवाइस SELinux के साथ सक्षम हो जाता है। अब आप या तो अनुकूलन में वर्णित एंड्रॉइड ऑपरेटिंग सिस्टम में अपने स्वयं के अतिरिक्त को समायोजित करने के लिए अपनी SELinux नीतियों को अनुकूलित कर सकते हैं या सत्यापन में शामिल अपने मौजूदा सेटअप को सत्यापित कर सकते हैं।

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

कार्यान्वयन

SELinux के साथ आरंभ करने के लिए:

  1. कर्नेल में SELinux सक्षम करें: CONFIG_SECURITY_SELINUX=y
  2. कर्नेल_सीएमडीलाइन या बूटकॉन्फिग पैरामीटर को बदलें ताकि:
    BOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
    या
    BOARD_BOOTCONFIG := androidboot.selinux=permissive
    यह केवल डिवाइस के लिए नीति के प्रारंभिक विकास के लिए है। आपके पास प्रारंभिक बूटस्ट्रैप नीति होने के बाद, इस पैरामीटर को हटा दें ताकि आपका डिवाइस लागू हो या यह सीटीएस विफल हो जाएगा।
  3. सिस्टम को परमिसिव में बूट करें और देखें कि बूट पर कौन से इनकार सामने आते हैं:
    Ubuntu 14.04 या नए पर:
    adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy
    
    Ubuntu 12.04 पर:
    adb pull /sys/fs/selinux/policy
    adb logcat -b all | audit2allow -p policy
    
  4. चेतावनियों के लिए आउटपुट का मूल्यांकन करें जो init: Warning! Service name needs a SELinux domain defined; please fix! निर्देशों और उपकरणों के लिए सत्यापन देखें।
  5. डिवाइस और अन्य नई फ़ाइलों की पहचान करें जिन्हें लेबलिंग की आवश्यकता है।
  6. अपनी वस्तुओं के लिए मौजूदा या नए लेबल का उपयोग करें। यह देखने के लिए *_contexts फ़ाइलों को देखें कि चीज़ों को पहले कैसे लेबल किया गया था और एक नया लेबल निर्दिष्ट करने के लिए लेबल अर्थों के ज्ञान का उपयोग करें। आदर्श रूप से, यह एक मौजूदा लेबल होगा जो नीति में फिट होगा, लेकिन कभी-कभी एक नए लेबल की आवश्यकता होगी, और उस लेबल तक पहुंच के लिए नियमों की आवश्यकता होगी। अपने लेबल को उपयुक्त संदर्भ फ़ाइलों में जोड़ें।
  7. उन डोमेन/प्रक्रियाओं की पहचान करें जिनके पास अपने स्वयं के सुरक्षा डोमेन होने चाहिए। आपको संभवतः प्रत्येक के लिए एक पूरी तरह से नई नीति लिखने की आवश्यकता होगी। उदाहरण के लिए, init से उत्पन्न सभी सेवाओं का अपना होना चाहिए। निम्नलिखित आदेश उन आदेशों को प्रकट करने में मदद करते हैं जो चालू रहते हैं (लेकिन सभी सेवाओं को ऐसे उपचार की आवश्यकता होती है):
    adb shell su -c ps -Z | grep init
    
    adb shell su -c dmesg | grep 'avc: '
    
  8. init. device .rc ऐसे किसी भी डोमेन की पहचान करने के लिए जिसका कोई डोमेन प्रकार नहीं है। अपनी विकास प्रक्रिया के प्रारंभ में ही उन्हें एक डोमेन दें ताकि init में नियम जोड़ने या अन्यथा उनकी अपनी नीति में मौजूद init एक्सेस को भ्रमित करने से बचा जा सके।
  9. BOARD_SEPOLICY_* वेरिएबल का उपयोग करने के लिए BOARD_CONFIG.mk सेट करें। इसे स्थापित करने के विवरण के लिए system/sepolicy में रीडमी देखें।
  10. init की जाँच करें. device .rc और fstab। device फ़ाइल बनाएं और सुनिश्चित करें कि mount का प्रत्येक उपयोग उचित रूप से लेबल किए गए फ़ाइल सिस्टम से मेल खाता है या एक context= mount विकल्प निर्दिष्ट है।
  11. प्रत्येक इनकार से गुजरें और प्रत्येक को ठीक से संभालने के लिए SELinux नीति बनाएं। अनुकूलन में उदाहरण देखें.

आपको एओएसपी में नीतियों से शुरुआत करनी चाहिए और फिर अपने अनुकूलन के लिए उन पर काम करना चाहिए। नीति रणनीति के बारे में अधिक जानकारी और इनमें से कुछ चरणों पर करीब से नज़र डालने के लिए, SELinux नीति लिखना देखें।

बक्सों का इस्तेमाल करें

यहां आपके स्वयं के सॉफ़्टवेयर और संबंधित SELinux नीतियों को तैयार करते समय विचार करने योग्य कारनामों के विशिष्ट उदाहरण दिए गए हैं:

सिम्लिंक - क्योंकि सिम्लिंक फाइलों के रूप में दिखाई देते हैं, उन्हें अक्सर फाइलों के रूप में पढ़ा जाता है, जिससे शोषण हो सकता है। उदाहरण के लिए, कुछ विशेषाधिकार प्राप्त घटक, जैसे कि init , कुछ फ़ाइलों की अनुमतियों को बदल देते हैं, कभी-कभी अत्यधिक खुले होने के लिए।

इसके बाद हमलावर उन फ़ाइलों को अपने नियंत्रण वाले कोड के सिम्लिंक से बदल सकते हैं, जिससे हमलावर को मनमानी फ़ाइलों को अधिलेखित करने की अनुमति मिलती है। लेकिन यदि आप जानते हैं कि आपका एप्लिकेशन कभी भी सिम्लिंक को पार नहीं करेगा, तो आप उसे SELinux के साथ ऐसा करने से रोक सकते हैं।

सिस्टम फ़ाइलें - सिस्टम फ़ाइलों के वर्ग पर विचार करें जिन्हें केवल सिस्टम सर्वर द्वारा संशोधित किया जाना चाहिए। फिर भी, चूंकि netd , init और vold रूट के रूप में चलते हैं, वे उन सिस्टम फ़ाइलों तक पहुंच सकते हैं। इसलिए यदि netd समझौता हो जाता है, तो यह उन फ़ाइलों और संभावित रूप से सिस्टम सर्वर से भी समझौता कर सकता है।

SELinux के साथ, आप उन फ़ाइलों को सिस्टम सर्वर डेटा फ़ाइलों के रूप में पहचान सकते हैं। इसलिए, एकमात्र डोमेन जिसके पास पढ़ने/लिखने की पहुंच है, वह सिस्टम सर्वर है। भले ही netd समझौता हो गया हो, यह डोमेन को सिस्टम सर्वर डोमेन पर स्विच नहीं कर सका और उन सिस्टम फ़ाइलों तक पहुंच नहीं सका, हालांकि यह रूट के रूप में चलता है।

ऐप डेटा - एक अन्य उदाहरण फ़ंक्शंस का वर्ग है जिसे रूट के रूप में चलना चाहिए लेकिन ऐप डेटा तक पहुंच नहीं मिलनी चाहिए। यह अविश्वसनीय रूप से उपयोगी है क्योंकि व्यापक दावे किए जा सकते हैं, जैसे कि एप्लिकेशन डेटा से असंबंधित कुछ डोमेन को इंटरनेट तक पहुंचने से प्रतिबंधित किया जा रहा है।

setattr - chmod और chown जैसे कमांड के लिए, आप फ़ाइलों के सेट की पहचान कर सकते हैं जहां संबंधित डोमेन setattr संचालित कर सकता है। इससे बाहर की किसी भी चीज़ को इन परिवर्तनों से प्रतिबंधित किया जा सकता है, यहाँ तक कि जड़ से भी। इसलिए कोई एप्लिकेशन उन लेबल वाले app_data_files के विरुद्ध chmod और chown चला सकता है, लेकिन shell_data_files या system_data_files नहीं।