SELinux नीति बनाना

इस पेज पर, SELinux नीति बनाने का तरीका बताया गया है. SELinux नीति, AOSP की मुख्य नीति (प्लैटफ़ॉर्म) और डिवाइस के हिसाब से बनी नीति (वेंडर) के कॉम्बिनेशन से बनाई जाती है. Android 4.4 से लेकर Android 7.0 तक के लिए, SELinux नीति के बिल्ड फ़्लो ने सभी sepolicy फ़्रैगमेंट को मर्ज किया. इसके बाद, रूट डायरेक्ट्री में मोनोलिथिक फ़ाइलें जनरेट की गईं. इसका मतलब है कि नीति में बदलाव होने पर, SoC वेंडर और ODM मैन्युफ़ैक्चरर, boot.img (A/B डिवाइसों के लिए) या system.img (A/B डिवाइसों के लिए) में बदलाव करते थे.

Android 8.0 और इसके बाद के वर्शन में, प्लैटफ़ॉर्म और वेंडर की नीति अलग-अलग बनाई जाती है. एसओसी और OEM, नीति के अपने हिस्सों को अपडेट कर सकते हैं. साथ ही, अपनी इमेज (जैसे, vendor.img और boot.img) बना सकते हैं. इसके बाद, वे इमेज को प्लैटफ़ॉर्म के अपडेट से अलग अपडेट कर सकते हैं.

हालांकि, मॉड्यूलर की गई SELinux नीति फ़ाइलें /vendor पार्टिशन पर सेव होती हैं. इसलिए, init प्रोसेस को सिस्टम और वेंडर पार्टिशन को पहले माउंट करना होगा, ताकि वह उन पार्टिशन से SELinux फ़ाइलें पढ़ सके और उन्हें कर्नेल में लोड करने से पहले, सिस्टम डायरेक्ट्री में मौजूद मुख्य SELinux फ़ाइलों के साथ मर्ज कर सके.

स्रोत फ़ाइलें

SELinux बनाने का लॉजिक इन फ़ाइलों में है:

  • external/selinux: बाहरी SELinux प्रोजेक्ट, जिसका इस्तेमाल, SELinux नीति और लेबल को कंपाइल करने के लिए, HOST कमांड लाइन की सुविधाओं को बनाने के लिए किया जाता है.
    • external/selinux/libselinux: Android, बाहरी libselinux प्रोजेक्ट के सिर्फ़ एक सबसेट का इस्तेमाल करता है. साथ ही, Android के हिसाब से कुछ बदलाव भी करता है. ज़्यादा जानकारी के लिए, external/selinux/README.android देखें.
    • external/selinux/libsepol:
      • chkcon: यह तय करना कि किसी बिनेरी नीति (होस्ट एक्सीक्यूटेबल) के लिए, सुरक्षा कॉन्टेक्स्ट मान्य है या नहीं.
      • libsepol: बाइनरी की सुरक्षा नीतियों (होस्ट स्टैटिक/शेयर की गई लाइब्रेरी, टारगेट स्टैटिक लाइब्रेरी) में बदलाव करने के लिए SELinux लाइब्रेरी.
    • external/selinux/checkpolicy: SELinux नीति कंपाइलर (होस्ट के लिए एक्सीक्यूटेबल: checkpolicy, checkmodule, और dispol). यह libsepol पर निर्भर करता है.
  • system/sepolicy: Android SELinux की मुख्य नीति के कॉन्फ़िगरेशन, जिनमें कॉन्टेक्स्ट और नीति फ़ाइलें शामिल हैं. यहां (system/sepolicy/Android.mk) सुरक्षा नीति बनाने का मुख्य लॉजिक भी मौजूद है.

system/sepolicy SELinux लागू करना में मौजूद फ़ाइलों के बारे में ज़्यादा जानकारी के लिए.

Android 7.x और इससे पहले के वर्शन

इस सेक्शन में बताया गया है कि Android 7.x और उससे पहले के वर्शन में, SELinux नीति कैसे बनाई जाती है.

Android 7.x और इससे पहले के वर्शन के लिए बिल्ड प्रोसेस

SELinux नीति, AOSP की मुख्य नीति को डिवाइस के हिसाब से किए गए बदलावों के साथ जोड़कर बनाई जाती है. इसके बाद, नीति को नीति कंपाइलर और कई तरह के जांच करने वाले टूल को भेज दिया जाता है. डिवाइस के हिसाब से कस्टमाइज़ेशन, डिवाइस के हिसाब से बनाई गई Boardconfig.mk फ़ाइल में बताए गए BOARD_SEPOLICY_DIRS वैरिएबल की मदद से किया जाता है. इस ग्लोबल बिल्ड वैरिएबल में, उन डायरेक्ट्री की सूची होती है जिनमें अन्य नीति फ़ाइलों को खोजने का क्रम तय होता है.

उदाहरण के लिए, किसी डिवाइस के लिए आखिरी SELinux कॉन्फ़िगरेशन जनरेट करने के लिए, SoC वेंडर और ODM, दोनों एक-एक डायरेक्ट्री जोड़ सकते हैं. एक डायरेक्ट्री, SoC के हिसाब से सेटिंग के लिए और दूसरी डायरेक्ट्री, डिवाइस के हिसाब से सेटिंग के लिए:

  • BOARD_SEPOLICY_DIRS += device/SOC/common/sepolicy
  • BOARD_SEPOLICY_DIRS += device/SoC/DEVICE/sepolicy

डिवाइस पर file_contexts.bin जनरेट करने के लिए, system/sepolicy और BOARD_SEPOLICY_DIRS में मौजूद file_contexts फ़ाइलों के कॉन्टेंट को जोड़ा जाता है:

इस इमेज में, Android 7.x के लिए SELinux बिल्ड लॉजिक दिखाया गया है.

पहली इमेज. SELinux का बिल्ड लॉजिक.

sepolicy फ़ाइल में कई सोर्स फ़ाइलें होती हैं:

  • सादा टेक्स्ट policy.conf, security_classes, initial_sids, *.te फ़ाइलों, genfs_contexts, और port_contexts को इस क्रम में जोड़कर जनरेट किया जाता है.
  • हर फ़ाइल (जैसे, security_classes) का कॉन्टेंट, system/sepolicy/ और BOARDS_SEPOLICY_DIRS में मौजूद एक ही नाम वाली फ़ाइलों को जोड़कर बनाया जाता है.
  • policy.conf को सिंटैक्स की जांच के लिए, SELinux कंपाइलर को भेजा जाता है और डिवाइस पर sepolicy के तौर पर बाइनरी फ़ॉर्मैट में कंपाइल किया जाता है.
    इस इमेज में, Android 7.x के लिए SELinux नीति फ़ाइल जनरेट करने वाली फ़ाइलें दिखाई गई हैं.

    दूसरी इमेज. SELinux नीति फ़ाइल.

SELinux फ़ाइलें

कंपाइल करने के बाद, Android 7.x और उससे पहले के वर्शन वाले डिवाइसों में आम तौर पर, SELinux से जुड़ी ये फ़ाइलें होती हैं:

  • selinux_version
  • sepolicy: नीति फ़ाइलों को जोड़ने के बाद बाइनरी आउटपुट (जैसे, security_classes, initial_sids, और *.te)
  • file_contexts
  • property_contexts
  • seapp_contexts
  • service_contexts
  • system/etc/mac_permissions.xml

ज़्यादा जानकारी के लिए, SELinux लागू करना लेख पढ़ें.

SELinux को शुरू करना

सिस्टम के चालू होने पर, SELinux अनुमति देने वाले मोड में होता है, न कि लागू करने वाले मोड में. init प्रोसेस ये काम करती है:

  • /sys/fs/selinux/load के ज़रिए, रैमडिस्क से sepolicy फ़ाइलों को कर्नेल में लोड करता है.
  • SELinux को लागू करने वाले मोड पर स्विच करता है.
  • SELinux डोमेन नियम को खुद पर लागू करने के लिए, re-exec() चलाता है.

बूट होने में लगने वाले समय को कम करने के लिए, re-exec() पर init प्रोसेस को जल्द से जल्द पूरा करें.

Android 8.0 और इसके बाद के वर्शन

Android 8.0 में, SELinux नीति को प्लैटफ़ॉर्म और वेंडर कॉम्पोनेंट में बांटा गया है. इससे, प्लैटफ़ॉर्म/वेंडर की नीति को अलग-अलग अपडेट किया जा सकता है. साथ ही, डिवाइस के साथ काम करने की सुविधा भी बनी रहती है.

प्लैटफ़ॉर्म की सुरक्षा नीति को प्लैटफ़ॉर्म के निजी और सार्वजनिक हिस्सों में बांटा गया है, ताकि वेंडर नीति लेखकों को खास तरह के और एट्रिब्यूट एक्सपोर्ट किए जा सकें. प्लैटफ़ॉर्म के सार्वजनिक टाइप/एट्रिब्यूट को किसी प्लैटफ़ॉर्म वर्शन के लिए, स्थिर एपीआई के तौर पर बनाए रखने की गारंटी है. प्लैटफ़ॉर्म मैपिंग फ़ाइलों का इस्तेमाल करके, कई वर्शन के लिए प्लैटफ़ॉर्म के पिछले सार्वजनिक टाइप/एट्रिब्यूट के साथ काम करने की गारंटी दी जा सकती है.

Android 8.0 के लिए बिल्ड प्रोसेस

Android 8.0 में SELinux की नीति, /system और /vendor के कुछ हिस्सों को मिलाकर बनाई गई है. इसे सही तरीके से सेट अप करने का लॉजिक, /platform/system/sepolicy/Android.mk में दिया गया है.

नीति इन जगहों पर मौजूद है:

जगह की जानकारी इसमें शामिल है
system/sepolicy/public प्लैटफ़ॉर्म का sepolicy API
system/sepolicy/private प्लैटफ़ॉर्म को लागू करने से जुड़ी जानकारी (वेंडर इसे अनदेखा कर सकते हैं)
system/sepolicy/vendor नीति और संदर्भ फ़ाइलें, जिनका इस्तेमाल वेंडर कर सकते हैं (वेंडर चाहें, तो इन फ़ाइलों को अनदेखा कर सकते हैं)
BOARD_SEPOLICY_DIRS वेंडर की सुरक्षा नीति
BOARD_ODM_SEPOLICY_DIRS (Android 9 और उसके बाद के वर्शन) Odm sepolicy
SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS (Android 11 और उसके बाद के वर्शन) System_ext का sepolicy API
SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS (Android 11 और उसके बाद के वर्शन) System_ext को लागू करने से जुड़ी जानकारी (वेंडर इस जानकारी को अनदेखा कर सकते हैं)
PRODUCT_PUBLIC_SEPOLICY_DIRS (Android 11 और उसके बाद के वर्शन) प्रॉडक्ट का sepolicy API
PRODUCT_PRIVATE_SEPOLICY_DIRS (Android 11 और उसके बाद के वर्शन) प्रॉडक्ट लागू करने की जानकारी (वेंडर इस जानकारी को अनदेखा कर सकते हैं)

बिल्ड सिस्टम इस नीति को लेता है और उससे जुड़े पार्टीशन पर system, system_ext, product, vendor, और odm नीति के कॉम्पोनेंट बनाता है. इसमें ये चरण शामिल हैं:

  1. नीतियों को SELinux कॉमन इंटरमीडियरी लैंग्वेज (सीआईएल) फ़ॉर्मैट में बदलना. खास तौर पर:
    1. सार्वजनिक प्लैटफ़ॉर्म की नीति (system + system_ext + product)
    2. निजी और सार्वजनिक नीति
    3. सार्वजनिक + वेंडर और BOARD_SEPOLICY_DIRS नीति
  2. वेंडर नीति के तहत, सार्वजनिक तौर पर उपलब्ध कराई गई नीति का वर्शन बनाना. सार्वजनिक CIL नीति का इस्तेमाल करके, सार्वजनिक + वेंडर + BOARD_SEPOLICY_DIRS नीति के बारे में बताया जाता है. इससे यह तय किया जाता है कि किन हिस्सों को ऐसे एट्रिब्यूट में बदलना चाहिए जिन्हें प्लैटफ़ॉर्म की नीति से जोड़ा जाएगा.
  3. प्लैटफ़ॉर्म और वेंडर पार्ट को लिंक करने वाली मैपिंग फ़ाइल बनाना. शुरुआत में, यह सिर्फ़ सार्वजनिक नीति के टाइप को, वेंडर नीति के उन एट्रिब्यूट से लिंक करता है जो उन टाइप से मिलते-जुलते हैं. बाद में, यह आने वाले समय में प्लैटफ़ॉर्म के वर्शन में सेव की जाने वाली फ़ाइल के लिए भी आधार देगा. इससे, इस प्लैटफ़ॉर्म के वर्शन को टारगेट करने वाली वेंडर नीति के साथ काम करने की सुविधा मिलेगी.
  4. नीति फ़ाइलों को जोड़ना (डिवाइस पर मौजूद और पहले से कंपाइल किए गए समाधान, दोनों के बारे में बताएं).
    1. मैपिंग, प्लैटफ़ॉर्म, और वेंडर की नीति को जोड़ें.
    2. आउटपुट बाइनरी नीति फ़ाइल को कंपाइल करें.

प्लैटफ़ॉर्म की सार्वजनिक सुरक्षा नीति

प्लैटफ़ॉर्म की सार्वजनिक सुरक्षा नीति में, system/sepolicy/public में बताई गई सभी चीज़ें शामिल होती हैं. प्लैटफ़ॉर्म यह मान सकता है कि सार्वजनिक नीति के तहत तय किए गए टाइप और एट्रिब्यूट, किसी प्लैटफ़ॉर्म के वर्शन के लिए, स्थिर एपीआई हैं. यह sepolicy का हिस्सा होता है, जिसे प्लैटफ़ॉर्म से एक्सपोर्ट किया जाता है. इस प्लैटफ़ॉर्म पर, वेंडर (यानी डिवाइस) नीति डेवलपर, डिवाइस के हिसाब से अतिरिक्त नीति लिख सकते हैं.

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

प्लैटफ़ॉर्म की निजी सुरक्षा नीति

प्लैटफ़ॉर्म की निजी सुरक्षा नीति में, /system/sepolicy/private में बताई गई सभी बातें शामिल होती हैं. नीति के इस हिस्से में, सिर्फ़ प्लैटफ़ॉर्म के लिए उपलब्ध टाइप, अनुमतियां, और प्लैटफ़ॉर्म की सुविधाओं के लिए ज़रूरी एट्रिब्यूट शामिल होते हैं. इन्हें vendor/device नीति लेखकों के लिए एक्सपोर्ट नहीं किया जाता. जिन लोगों ने प्लैटफ़ॉर्म की नीति नहीं लिखी है उन्हें नीति के एक्सटेंशन, प्लैटफ़ॉर्म की निजी सुरक्षा नीति में बताए गए टाइप/एट्रिब्यूट/नियमों के आधार पर नहीं लिखने चाहिए. इसके अलावा, इन नियमों में बदलाव किया जा सकता है या ये सिर्फ़ फ़्रेमवर्क के अपडेट के तहत दिख सकते हैं.

प्लैटफ़ॉर्म की निजी मैपिंग

प्लैटफ़ॉर्म की निजी मैपिंग में नीति के ऐसे स्टेटमेंट शामिल होते हैं जो पिछले प्लैटफ़ॉर्म वर्शन की प्लैटफ़ॉर्म की सार्वजनिक नीति में ज़ाहिर किए गए एट्रिब्यूट को, मौजूदा प्लैटफ़ॉर्म की सार्वजनिक नीति में इस्तेमाल किए गए टाइप के साथ मैप करते हैं. इससे यह पक्का होता है कि प्लैटफ़ॉर्म के पिछले सार्वजनिक सेक्योरिटी नीति वर्शन के प्लैटफ़ॉर्म के सार्वजनिक एट्रिब्यूट के आधार पर लिखी गई वेंडर नीति काम करती रहेगी. वर्शन, किसी प्लैटफ़ॉर्म वर्शन के लिए AOSP में सेट किए गए PLATFORM_SEPOLICY_VERSION बिल्ड वैरिएबल पर आधारित होता है. प्लैटफ़ॉर्म के हर पुराने वर्शन के लिए, एक अलग मैपिंग फ़ाइल मौजूद होती है. इस वर्शन के लिए, प्लैटफ़ॉर्म को वेंडर की नीति स्वीकार करनी होती है. ज़्यादा जानकारी के लिए, काम करने की सुविधा देखें.

Android 11 और उसके बाद के वर्शन

system_ext और प्रॉडक्ट sepolicy

Android 11 में, system_ext नीति और प्रॉडक्ट नीति जोड़ी गई है. प्लैटफ़ॉर्म की सेक्योरिटी नीति की तरह ही, system_ext नीति और प्रॉडक्ट की नीति को भी सार्वजनिक नीति और निजी नीति में बांटा गया है.

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

निजी नीति में, सिर्फ़ system_ext और सिर्फ़ प्रॉडक्ट के टाइप, अनुमतियां, और एट्रिब्यूट शामिल होते हैं. ये system_ext और प्रॉडक्ट के पार्टीशन की सुविधाओं के लिए ज़रूरी होते हैं. निजी नीति, वेंडर को नहीं दिखती. इसका मतलब है कि ये नियम इंटरनल हैं और इनमें बदलाव किया जा सकता है.

system_ext और प्रॉडक्ट मैपिंग

system_ext और प्रॉडक्ट को, तय किए गए सार्वजनिक टाइप को वेंडर में एक्सपोर्ट करने की अनुमति है. हालांकि, यह पक्का करना कि सभी पार्टनर के ऐप्लिकेशन एक-दूसरे के साथ काम करते हों, इसकी ज़िम्मेदारी हर पार्टनर की है. साथ काम करने वाले पार्टनर, अपनी मैपिंग फ़ाइलें उपलब्ध करा सकते हैं. इन फ़ाइलों की मदद से, पिछले वर्शन के एट्रिब्यूट के वर्शन को, मौजूदा सार्वजनिक सुरक्षा नीति में इस्तेमाल किए जाने वाले कंक्रीट टाइप से मैप किया जा सकता है.

  • system_ext के लिए मैपिंग फ़ाइल इंस्टॉल करने के लिए, {SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil में अपनी पसंद की मैपिंग जानकारी वाली cil फ़ाइल डालें. इसके बाद, system_ext_{ver}.cil को PRODUCT_PACKAGES में जोड़ें.
  • प्रॉडक्ट के लिए मैपिंग फ़ाइल इंस्टॉल करने के लिए, {PRODUCT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil में अपनी पसंद की मैपिंग जानकारी वाली cil फ़ाइल डालें. इसके बाद, product_{ver}.cil को PRODUCT_PACKAGES में जोड़ें.

उदाहरण देखें, जिसमें redbull डिवाइस के प्रॉडक्ट पार्टीशन की मैपिंग फ़ाइल जोड़ी गई है.

पहले से कंपाइल की गई SELinux नीति

init, SELinux को चालू करने से पहले, system, system_ext, product, vendor, और odm जैसे सभी सेक्शन से सभी सीआईएल फ़ाइलें इकट्ठा करता है. इसके बाद, उन्हें बाइनरी नीति में कंपाइल करता है. यह ऐसा फ़ॉर्मैट होता है जिसे कर्नेल में लोड किया जा सकता है.init कंपाइल करने में समय लगता है (आम तौर पर 1-2 सेकंड), इसलिए CIL फ़ाइलों को बिल्ड के समय पहले से कंपाइल किया जाता है और इनपुट CIL फ़ाइलों के sha256 हैश के साथ, /vendor/etc/selinux/precompiled_sepolicy या /odm/etc/selinux/precompiled_sepolicy में डाला जाता है. रनटाइम के दौरान, init हैश की तुलना करके यह जांच करता है कि नीति की कोई फ़ाइल अपडेट हुई है या नहीं. अगर कुछ भी नहीं बदला है, तो init पहले से संकलित नीति को लोड करता है. अगर ऐसा नहीं है, तो init फ़्लाइट पर कंपाइल करता है और पहले से कंपाइल किए गए के बजाय इसका इस्तेमाल करता है.

खास तौर पर, पहले से संकलित की गई नीति का इस्तेमाल तब किया जाता है, जब ये सभी शर्तें पूरी होती हैं. यहां, {partition} उस पार्टीशन को दिखाता है जहां पहले से संकलित नीति मौजूद है: vendor या odm.

  • /system/etc/selinux/plat_sepolicy_and_mapping.sha256 और /{partition}/etc/selinux/precompiled_sepolicy.plat_sepolicy_and_mapping.sha256 दोनों मौजूद हैं और एक जैसे हैं.
  • /system_ext/etc/selinux/system_ext_sepolicy_and_mapping.sha256 और /{partition}/etc/selinux/precompiled_sepolicy.system_ext_sepolicy_and_mapping.sha256 दोनों एट्रिब्यूट मौजूद नहीं हैं. इसके अलावा, दोनों मौजूद हों और एक जैसे हों.
  • /product/etc/selinux/product_sepolicy_and_mapping.sha256 और /{partition}/etc/selinux/precompiled_sepolicy.product_sepolicy_and_mapping.sha256 दोनों एट्रिब्यूट मौजूद नहीं हैं. इसके अलावा, दोनों मौजूद हों और एक जैसे हों.

अगर उनमें से किसी भी पैरामीटर में अंतर होता है, तो init डिवाइस पर कॉम्पाइल करने के पाथ का इस्तेमाल करता है. ज़्यादा जानकारी के लिए, system/core/init/selinux.cpp देखें.