नीति के साथ काम करने की सुविधा

इस लेख में बताया गया है कि Android, प्लैटफ़ॉर्म के ओटीए (ऑनलाइन ट्रांसफ़र) के साथ नीति के साथ काम करने से जुड़ी समस्याओं को कैसे मैनेज करता है. ऐसा तब होता है, जब प्लैटफ़ॉर्म की नई SELinux सेटिंग, वेंडर की पुरानी SELinux सेटिंग से अलग हो सकती हैं.

Treble पर आधारित SELinux नीति के डिज़ाइन में, प्लैटफ़ॉर्म और वेंडर नीति के बीच बाइनरी के अंतर को ध्यान में रखा जाता है. अगर वेंडर के पार्टीशन, platform < vendor < oem जैसी डिपेंडेंसी जनरेट करते हैं, तो स्कीम ज़्यादा जटिल हो जाती है.

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

  • वर्शन के लिए, एक्सपोर्ट की गई प्लैटफ़ॉर्म-सार्वजनिक नीति को एट्रिब्यूट के तौर पर लिखा जाएगा.
  • नीति लिखने में आसानी के लिए, एक्सपोर्ट किए गए टाइप को नीति बनाने की प्रोसेस के तहत, वर्शन वाले एट्रिब्यूट में बदल दिया जाएगा. सार्वजनिक टाइप का इस्तेमाल, वेंडर कॉन्टेक्स्ट फ़ाइलों से मिले लेबल करने के फ़ैसलों में भी सीधे तौर पर किया जा सकता है.

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

ऑब्जेक्ट का मालिकाना हक और लेबल करना

Android 8.0 और उसके बाद के वर्शन में नीति में बदलाव करते समय, हर ऑब्जेक्ट के लिए मालिकाना हक की जानकारी साफ़ तौर पर दी जानी चाहिए, ताकि प्लैटफ़ॉर्म और वेंडर की नीति को अलग रखा जा सके. उदाहरण के लिए, अगर वेंडर /dev/foo को लेबल करता है और प्लैटफ़ॉर्म, बाद में किसी ओटीए में /dev/foo को लेबल करता है, तो डिवाइस का व्यवहार तय नहीं होगा. SELinux के लिए, यह लेबल करने में होने वाली गड़बड़ी के तौर पर दिखता है. डिवाइस नोड में सिर्फ़ एक लेबल हो सकता है, जो आखिरी में लागू किए गए लेबल पर रीज़ॉल्व होता है. इसकी वजह से:

  • जिन प्रोसेस को लागू नहीं किए गए लेबल का ऐक्सेस चाहिए उनके पास संसाधन का ऐक्सेस नहीं रहेगा.
  • गलत डिवाइस नोड बनाने की वजह से, फ़ाइल का ऐक्सेस पाने वाली प्रोसेस रुक सकती हैं.

सिस्टम प्रॉपर्टी में, नामों के मेल खाने की संभावना भी होती है. इससे सिस्टम (और SELinux लेबल) पर, काम करने का कोई तय तरीका नहीं बन पाता. प्लैटफ़ॉर्म और वेंडर लेबल के बीच, किसी भी ऐसे ऑब्जेक्ट के लिए टकराव हो सकता है जिसमें SELinux लेबल हो. इसमें प्रॉपर्टी, सेवाएं, प्रोसेस, फ़ाइलें, और सॉकेट शामिल हैं. इन समस्याओं से बचने के लिए, इन ऑब्जेक्ट का मालिकाना हक साफ़ तौर पर बताएं.

लेबल के नाम एक जैसे होने के अलावा, SELinux टाइप/एट्रिब्यूट के नाम भी एक जैसे हो सकते हैं. टाइप/एट्रिब्यूट के नाम का मेल खाने पर, नीति कंपाइलर से जुड़ी गड़बड़ी हमेशा दिखेगी.

टाइप/एट्रिब्यूट नेमस्पेस

SELinux, एक ही टाइप/एट्रिब्यूट के लिए कई एलान करने की अनुमति नहीं देता. डुप्लीकेट एलान वाली नीति को कंपाइल नहीं किया जा सकेगा. टाइप और एट्रिब्यूट के नाम के मेल खाने से बचने के लिए, सभी वेंडर एलान को नेमस्पेस में रखा जाना चाहिए. नेमस्पेस की शुरुआत vendor_ से होनी चाहिए.

type foo, domain;  type vendor_foo, domain;

सिस्टम प्रॉपर्टी और प्रोसेस लेबल करने का मालिकाना हक

प्रॉपर्टी नेमस्पेस का इस्तेमाल करके, लेबल के नामों में होने वाली गड़बड़ियों से बचा जा सकता है. प्लैटफ़ॉर्म प्रॉपर्टी की आसानी से पहचान करने और एक्सपोर्ट की गई प्लैटफ़ॉर्म प्रॉपर्टी का नाम बदलते या जोड़ते समय नामों के टकराव से बचने के लिए, पक्का करें कि सभी वेंडर प्रॉपर्टी के अपने प्रीफ़िक्स हों:

प्रॉपर्टी का टाइप स्वीकार किए जा सकने वाले प्रीफ़िक्स
प्रॉपर्टी कंट्रोल करना ctl.vendor.
ctl.start$vendor.
ctl.stop$vendor.
init.svc.vendor.
read-writable vendor.
रीड-ओनली ro.vendor.
ro.boot.
ro.hardware.
परसिस्टेंट persist.vendor.

वेंडर, ro.boot.* (जो कि kernelcmdline से आता है) और ro.hardware.* (हार्डवेयर से जुड़ी एक साफ़ तौर पर दिखने वाली प्रॉपर्टी) का इस्तेमाल करना जारी रख सकते हैं.

init rc फ़ाइलों में मौजूद सभी वेंडर सेवाओं के लिए, vendor. नॉन-सिस्टम पार्टीशन की init rc फ़ाइलों में सेवाएं होनी चाहिए. वेंडर प्रॉपर्टी के लिए SELinux लेबल पर भी इसी तरह के नियम लागू होते हैं (vendor_वेंडर प्रॉपर्टी के लिए).

फ़ाइल का मालिकाना हक

फ़ाइलों के लिए, एक ही नाम का इस्तेमाल होने से रोकना मुश्किल है. इसकी वजह यह है कि आम तौर पर, प्लैटफ़ॉर्म और वेंडर की नीति, दोनों में सभी फ़ाइल सिस्टम के लिए लेबल उपलब्ध कराए जाते हैं. टाइप के नाम के उलट, फ़ाइलों को नेमस्पेस देना काम का नहीं है, क्योंकि उनमें से कई को कर्नेल बनाता है. इन समस्याओं से बचने के लिए, इस सेक्शन में फ़ाइल सिस्टम के नाम रखने के लिए दिए गए दिशा-निर्देशों का पालन करें. Android 8.0 के लिए, ये सुझाव हैं. इन्हें लागू करने के लिए, तकनीकी तौर पर कोई कार्रवाई नहीं की जाती. आने वाले समय में, इन सुझावों को वेंडर टेस्ट सुइट (वीटीएस) लागू करेगा.

सिस्टम (/system)

सिर्फ़ सिस्टम इमेज में file_contexts, service_contexts वगैरह के ज़रिए /system कॉम्पोनेंट के लिए लेबल होने चाहिए. अगर /vendor नीति में /system कॉम्पोनेंट के लिए लेबल जोड़े जाते हैं, तो हो सकता है कि सिर्फ़ फ़्रेमवर्क के लिए ओटीए अपडेट न किया जा सके.

वेंडर (/vendor)

AOSP SELinux नीति, vendor partition के उन हिस्सों को पहले से ही लेबल कर देती है जिनसे प्लैटफ़ॉर्म इंटरैक्ट करता है. इससे, प्लैटफ़ॉर्म प्रोसेस के लिए SELinux नियम लिखे जा सकते हैं, ताकि वे vendor partition के हिस्सों को ऐक्सेस और/या उनसे इंटरैक्ट कर सकें. उदाहरण:

/vendor पाथ प्लैटफ़ॉर्म से मिला लेबल प्लैटफ़ॉर्म, लेबल के हिसाब से प्रोसेस करता है
/vendor(/.*)? vendor_file फ़्रेमवर्क, ueventd वगैरह में मौजूद सभी एचएएल क्लाइंट
/vendor/framework(/.*)? vendor_framework_file dex2oat, appdomain वगैरह.
/vendor/app(/.*)? vendor_app_file dex2oat, installd, idmap वगैरह.
/vendor/overlay(/.*) vendor_overlay_file system_server, zygote, idmap वगैरह.

इसलिए, vendor के सेगमेंट में अन्य फ़ाइलों को लेबल करते समय, कुछ खास नियमों का पालन करना ज़रूरी है. ये नियम neverallows के ज़रिए लागू किए जाते हैं:

  • vendor_file , vendor partition में मौजूद सभी फ़ाइलों के लिए डिफ़ॉल्ट लेबल होना चाहिए. प्लैटफ़ॉर्म की नीति के मुताबिक, पासथ्रू एचएएल लागू करने के लिए, ऐसा करना ज़रूरी है.
  • वेंडर SEPolicy के ज़रिए vendor partition में जोड़े गए सभी नए exec_types में vendor_file_type एट्रिब्यूट होना चाहिए. इसे कभी अनुमति न दें सेट करने पर, यह पाबंदी लागू होती है.
  • आने वाले समय में प्लैटफ़ॉर्म/फ़्रेमवर्क के अपडेट से होने वाली समस्याओं से बचने के लिए, vendor सेक्शन में exec_types के अलावा किसी और फ़ाइल को लेबल न करें.
  • AOSP की पहचान की गई एक ही प्रोसेस के एचएएल के लिए, सभी लाइब्रेरी डिपेंडेंसी को same_process_hal_file. के तौर पर लेबल किया जाना चाहिए

Procfs (/proc)

/proc में मौजूद फ़ाइलों को सिर्फ़ genfscon लेबल का इस्तेमाल करके लेबल किया जा सकता है. Android 7.0 में, procfs में फ़ाइलों को लेबल करने के लिए, प्लैटफ़ॉर्म और वेंडर, दोनों की नीति में genfscon का इस्तेमाल किया गया था.

सुझाव: सिर्फ़ प्लैटफ़ॉर्म की नीति के लेबल /proc. अगर vendor प्रोसेस को /proc में मौजूद उन फ़ाइलों का ऐक्सेस चाहिए जो फ़िलहाल डिफ़ॉल्ट लेबल (proc) से लेबल की गई हैं, तो वेंडर की नीति को साफ़ तौर पर उन्हें लेबल नहीं करना चाहिए. इसके बजाय, वेंडर डोमेन के लिए नियम जोड़ने के लिए, सामान्य proc टाइप का इस्तेमाल करना चाहिए. इससे प्लैटफ़ॉर्म के अपडेट, procfs के ज़रिए दिखाए जाने वाले आने वाले समय के कर्नेल इंटरफ़ेस को शामिल कर पाते हैं. साथ ही, ज़रूरत के हिसाब से उन्हें साफ़ तौर पर लेबल कर पाते हैं.

Debugfs (/sys/kernel/debug)

Debugfs को file_contexts और genfscon, दोनों में लेबल किया जा सकता है. Android 7.0 से Android 10 में, प्लैटफ़ॉर्म और वेंडर, दोनों लेबल के लिए debugfs.

Android 11 में, debugfs को प्रोडक्शन डिवाइसों पर ऐक्सेस या माउंट नहीं किया जा सकता. डिवाइस बनाने वाली कंपनियों को debugfs हटाना चाहिए.

Tracefs (/sys/kernel/debug/tracing)

Tracefs को file_contexts और genfscon, दोनों में लेबल किया जा सकता है. Android 7.0 में, सिर्फ़ प्लैटफ़ॉर्म लेबल दिखते हैं tracefs.

सुझाव: सिर्फ़ प्लैटफ़ॉर्म को tracefs लेबल करने की अनुमति है.

Sysfs (/sys)

/sys में मौजूद फ़ाइलों को file_contexts और genfscon, दोनों का इस्तेमाल करके लेबल किया जा सकता है. Android 7.0 में, प्लैटफ़ॉर्म और वेंडर, दोनों sysfs में फ़ाइलों को लेबल करने के लिए genfscon का इस्तेमाल करते हैं.

सुझाव: प्लैटफ़ॉर्म, sysfs ऐसे नोड को लेबल कर सकता है जो किसी डिवाइस के लिए नहीं हैं. ऐसा न करने पर, सिर्फ़ वेंडर ही फ़ाइलों को लेबल कर सकता है.

tmpfs (/dev)

/dev में मौजूद फ़ाइलों को file_contexts में लेबल किया जा सकता है. Android 7.0 में, प्लैटफ़ॉर्म और वेंडर, दोनों लेबल की फ़ाइलें यहां मौजूद हैं.

सुझाव: वेंडर सिर्फ़ /dev/vendor में फ़ाइलों को लेबल कर सकता है (उदाहरण के लिए, /dev/vendor/foo, /dev/vendor/socket/bar).

Rootfs (/)

/ में मौजूद फ़ाइलों को file_contexts में लेबल किया जा सकता है. Android 7.0 में, प्लैटफ़ॉर्म और वेंडर, दोनों लेबल की फ़ाइलें यहां मौजूद हैं.

सुझाव: सिर्फ़ सिस्टम, / में फ़ाइलों को लेबल कर सकता है.

डेटा (/data)

डेटा को file_contexts और seapp_contexts के कॉम्बिनेशन से लेबल किया जाता है.

सुझाव: /data/vendor के बाहर वेंडर लेबल करने की अनुमति न दें. सिर्फ़ प्लैटफ़ॉर्म, /data के अन्य हिस्सों को लेबल कर सकता है.

Genfs लेबल का वर्शन

वेंडर एपीआई लेवल 202504 से, system/sepolicy/compat/plat_sepolicy_genfs_{ver}.cil में genfscon के साथ असाइन किए गए नए SELinux लेबल, वेंडर के पुराने PARTITION के लिए ज़रूरी नहीं हैं. इससे, पुराने वेंडर पार्टीशन में SEPolicy को लागू करने की मौजूदा सुविधा बनी रहती है. इसे Makefile वैरिएबल BOARD_GENFS_LABELS_VERSION से कंट्रोल किया जाता है, जो /vendor/etc/selinux/genfs_labels_version.txt में सेव होता है.

उदाहरण:

  • वेंडर एपीआई लेवल 202404 में, /sys/class/udc नोड को डिफ़ॉल्ट रूप से sysfs के तौर पर लेबल किया गया है.
  • वेंडर एपीआई लेवल 202504 से, /sys/class/udc को लेबल किया गया है sysfs_udc.

हालांकि, हो सकता है कि /sys/class/udc का इस्तेमाल, एपीआई लेवल 202404 का इस्तेमाल करने वाले वेंडर पार्टिशन में किया जा रहा हो. ऐसा, डिफ़ॉल्ट sysfs लेबल या वेंडर के हिसाब से बने लेबल के साथ किया जा सकता है. /sys/class/udc को बिना किसी शर्त के sysfs_udc के तौर पर लेबल करने से, इन वेंडर के पार्टिशन के साथ काम करने की सुविधा बंद हो सकती है. BOARD_GENFS_LABELS_VERSION को चुनने पर, प्लैटफ़ॉर्म पुराने वेंडर के सेगमेंट के लिए, पिछले लेबल और अनुमतियों का इस्तेमाल करता रहता है.

BOARD_GENFS_LABELS_VERSION, वेंडर के एपीआई लेवल से ज़्यादा या उसके बराबर हो सकता है. उदाहरण के लिए, एपीआई लेवल 202404 का इस्तेमाल करने वाले वेंडर पार्टिशन, BOARD_GENFS_LABELS_VERSION को 202504 पर सेट कर सकते हैं, ताकि वे 202504 में लॉन्च किए गए नए लेबल इस्तेमाल कर सकें. 202504 के लिए खास तौर पर बनाए गए genfs लेबल की सूची देखें.

genfscon नोड को लेबल करते समय, प्लैटफ़ॉर्म को वेंडर के पुराने पार्टीशन को ध्यान में रखना चाहिए. साथ ही, ज़रूरत पड़ने पर, काम करने के लिए फ़ॉलबैक मैकेनिज्म लागू करना चाहिए. प्लैटफ़ॉर्म, genfs लेबल के वर्शन के बारे में क्वेरी करने के लिए, सिर्फ़ प्लैटफ़ॉर्म के लिए उपलब्ध लाइब्रेरी का इस्तेमाल कर सकता है.

  • नेटिव ऐप्लिकेशन में, libgenfslabelsversion का इस्तेमाल करें. libgenfslabelsversion की हेडर फ़ाइल के लिए, genfslabelsversion.h देखें.
  • Java में, android.os.SELinux.getGenfsLabelsVersion() का इस्तेमाल करें.

डिवाइस के साथ काम करने की जानकारी देने वाले एट्रिब्यूट

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

नीति को ज़्यादातर मौजूदा टाइप के हिसाब से लिखा जाता है:

allow source_type target_type:target_class permission(s);

ऐसा इसलिए होता है, क्योंकि नीति को सभी तरह की जानकारी के साथ लिखा गया था. हालांकि, अगर वेंडर की नीति और प्लैटफ़ॉर्म की नीति में अलग-अलग टाइप का इस्तेमाल किया जाता है और किसी खास ऑब्जेक्ट का लेबल सिर्फ़ उनमें से किसी एक नीति में बदलता है, तो दूसरी नीति में वह नीति हो सकती है जिस पर पहले भरोसा किया गया था और जिसका ऐक्सेस मिल गया है या खो गया है. उदाहरण के लिए:

File_contexts:
/sys/A   u:object_r:sysfs:s0
Platform: allow p_domain sysfs:class perm;
Vendor: allow v_domain sysfs:class perm;

इसे इनमें बदला जा सकता है:

File_contexts:
/sys/A   u:object_r:sysfs_A:s0

हालांकि, वेंडर की नीति पहले जैसी ही रहेगी, लेकिन नए sysfs_A टाइप के लिए नीति न होने की वजह से, v_domain का ऐक्सेस हट जाएगा.

एट्रिब्यूट के हिसाब से नीति तय करके, हम ऑब्जेक्ट को ऐसा टाइप दे सकते हैं जिसमें प्लैटफ़ॉर्म और वेंडर कोड, दोनों के लिए नीति से जुड़ा एट्रिब्यूट हो. ऐसा सभी टाइप के लिए किया जा सकता है, ताकि एट्रिब्यूट-नीति को असरदार तरीके से बनाया जा सके. इसमें, कॉन्क्रीट टाइप का कभी इस्तेमाल नहीं किया जाता. आम तौर पर, ऐसा सिर्फ़ नीति के उन हिस्सों के लिए ज़रूरी होता है जो प्लैटफ़ॉर्म और वेंडर के बीच ओवरलैप होते हैं. इन हिस्सों को प्लैटफ़ॉर्म की सार्वजनिक नीति के तौर पर बताया और उपलब्ध कराया जाता है. यह नीति, वेंडर की नीति के हिस्से के तौर पर बनाई जाती है.

सार्वजनिक नीति को वर्शन वाले एट्रिब्यूट के तौर पर तय करने से, नीति के साथ काम करने के दो लक्ष्य पूरे होते हैं:

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

नीति लिखने की सुविधा

नीति बनाने के लिए, किसी खास वर्शन में हुए बदलावों के बारे में जानकारी नहीं होनी चाहिए. इस लक्ष्य को पूरा करने के लिए, Android 8.0 में प्लैटफ़ॉर्म की सार्वजनिक नीति के टाइप और उनके एट्रिब्यूट के बीच मैपिंग की सुविधा शामिल की गई है. टाइप foo को एट्रिब्यूट foo_vN पर मैप किया गया है, जहां N टारगेट किया गया वर्शन है. vN, PLATFORM_SEPOLICY_VERSION बिल्ड वैरिएबल से मेल खाता है और यह MM.NN फ़ॉर्मैट का होता है. इसमें MM, प्लैटफ़ॉर्म के SDK टूल के नंबर से मेल खाता है और NN, प्लैटफ़ॉर्म की सुरक्षा नीति से जुड़ा वर्शन होता है.

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

allow source_foo target_bar:class perm; के तौर पर एक्सपोर्ट की गई प्लैटफ़ॉर्म-सार्वजनिक नीति, वेंडर नीति के हिस्से के तौर पर शामिल की जाती है. कंपाइल (इसमें संबंधित वर्शन शामिल है) के दौरान, इसे उस नीति में बदल दिया जाता है जो डिवाइस के वेंडर हिस्से में जाएगी. इसे बदली गई कॉमन इंटरमीडियरी लैंग्वेज (सीआईएल) में दिखाया जाता है:

 (allow source_foo_vN target_bar_vN (class (perm)))

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

नीति में अंतर

हर टाइप के आखिर में _vN जोड़कर, एट्रिब्यूट अपने-आप बनने की सुविधा का इस्तेमाल करने पर, वर्शन के अंतर के हिसाब से एट्रिब्यूट को टाइप के हिसाब से मैप किए बिना कुछ नहीं होता. Android, एट्रिब्यूट के वर्शन के बीच मैपिंग और उन एट्रिब्यूट के टाइप की मैपिंग को बनाए रखता है. यह ऊपर बताई गई मैपिंग फ़ाइलों में, स्टेटमेंट के साथ किया जाता है, जैसे कि (सीआईएल):

(typeattributeset foo_vN (foo))

प्लैटफ़ॉर्म अपग्रेड

नीचे दिए गए सेक्शन में, प्लैटफ़ॉर्म अपग्रेड करने की स्थितियों के बारे में बताया गया है.

एक जैसे टाइप

यह स्थिति तब होती है, जब कोई ऑब्जेक्ट नीति के वर्शन में लेबल नहीं बदलता. यह सोर्स और टारगेट टाइप के लिए एक जैसा होता है. इसे /dev/binder के साथ देखा जा सकता है, जिसे सभी रिलीज़ में binder_device के तौर पर लेबल किया गया है. बदली गई नीति में इसे इस तरह दिखाया गया है:

binder_device_v1 … binder_device_vN

v1 से v2 पर अपग्रेड करते समय, प्लैटफ़ॉर्म की नीति में ये चीज़ें होनी चाहिए:

type binder_device; -> (type binder_device) (in CIL)

v1 मैपिंग फ़ाइल (सीआईएल) में:

(typeattributeset binder_device_v1 (binder_device))

v2 मैपिंग फ़ाइल (सीआईएल) में:

(typeattributeset binder_device_v2 (binder_device))

वेंडर नीति (सीआईएल) के वर्शन 1 में:

(typeattribute binder_device_v1)
(allow binder_device_v1 )

वेंडर नीति (सीआईएल) के वर्शन 2 में:

(typeattribute binder_device_v2)
(allow binder_device_v2 )
नए टाइप

यह स्थिति तब होती है, जब प्लैटफ़ॉर्म पर कोई नया टाइप जोड़ा जाता है. ऐसा नई सुविधाएं जोड़ते समय या नीति को सख्त करते समय हो सकता है.

  • नई सुविधा. जब टाइप किसी ऐसे ऑब्जेक्ट को लेबल कर रहा हो जो पहले मौजूद नहीं था (जैसे, नई सेवा की प्रोसेस), तो वेंडर कोड पहले सीधे तौर पर उससे इंटरैक्ट नहीं करता था. इसलिए, उससे जुड़ी कोई नीति मौजूद नहीं है. टाइप से जुड़े नए एट्रिब्यूट के लिए, पिछले वर्शन में कोई एट्रिब्यूट नहीं है. इसलिए, उस वर्शन को टारगेट करने वाली मैपिंग फ़ाइल में, एट्रिब्यूट की एंट्री की ज़रूरत नहीं होगी.
  • नीति को सख्त करना. जब टाइप, नीति को सख्त करने के बारे में बताता है, तो नए टाइप के एट्रिब्यूट को पिछले टाइप के एट्रिब्यूट की चेन से लिंक करना ज़रूरी है. यह उसी तरह है जैसे पिछले उदाहरण में /sys/A को sysfs से sysfs_A में बदला गया था. वेंडर कोड, sysfs को ऐक्सेस करने की अनुमति देने वाले नियम पर निर्भर करता है. साथ ही, उसे उस नियम को नए टाइप के एट्रिब्यूट के तौर पर शामिल करना होगा.

v1 से v2 पर अपग्रेड करते समय, प्लैटफ़ॉर्म की नीति में ये चीज़ें होनी चाहिए:

type sysfs_A; -> (type sysfs_A) (in CIL)
type sysfs; (type sysfs) (in CIL)

v1 मैपिंग फ़ाइल (सीआईएल) में:

(typeattributeset sysfs_v1 (sysfs sysfs_A))

v2 मैपिंग फ़ाइल (सीआईएल) में:

(typeattributeset sysfs_v2 (sysfs))
(typeattributeset sysfs_A_v2 (sysfs_A))

वेंडर नीति (सीआईएल) के वर्शन 1 में:

(typeattribute sysfs_v1)
(allow  sysfs_v1 )

वेंडर नीति (सीआईएल) के वर्शन 2 में:

(typeattribute sysfs_A_v2)
(allow  sysfs_A_v2 )
(typeattribute sysfs_v2)
(allow  sysfs_v2 )
हटाए गए टाइप

यह स्थिति (असामान्य) तब होती है, जब किसी टाइप को हटाया जाता है. ऐसा तब हो सकता है, जब:

  • यह मौजूद रहता है, लेकिन उसे एक अलग लेबल मिलता है.
  • प्लैटफ़ॉर्म से हटा दिया जाता है.

नीति में ढील देने के दौरान, किसी टाइप को हटा दिया जाता है और उस टाइप से लेबल किए गए ऑब्जेक्ट को कोई दूसरा, पहले से मौजूद लेबल दिया जाता है. यह एट्रिब्यूट मैपिंग को मर्ज करने के बारे में बताता है: वेंडर कोड अब भी उस एट्रिब्यूट की मदद से ऑब्जेक्ट को ऐक्सेस कर सकता है जो पहले उसमें मौजूद था. हालांकि, सिस्टम का बाकी हिस्सा अब उसे नए एट्रिब्यूट की मदद से ऐक्सेस कर सकता है.

अगर एट्रिब्यूट को किसी नए एट्रिब्यूट पर स्विच किया गया है, तो फिर से लेबल करना, नए टाइप के मामले में ठीक वैसा ही है. हालांकि, जब किसी मौजूदा लेबल का इस्तेमाल किया जाता है, तो पुराने एट्रिब्यूट के नए टाइप को जोड़ने से, इस टाइप से लेबल किए गए अन्य ऑब्जेक्ट भी नए तौर पर ऐक्सेस किए जा सकेंगे. प्लैटफ़ॉर्म पर ऐसा ही होता है. साथ ही, इसे काम करने के लिए ज़रूरी माना जाता है.

(typeattribute sysfs_v1)
(allow  sysfs_v1 )

उदाहरण के लिए, वर्शन 1: टाइप को छोटा करना (sysfs_A को हटाना)

v1 से v2 पर अपग्रेड करते समय, प्लैटफ़ॉर्म की नीति में ये चीज़ें होनी चाहिए:

type sysfs; (type sysfs) (in CIL)

v1 मैपिंग फ़ाइल (सीआईएल) में:

(typeattributeset sysfs_v1 (sysfs))
(type sysfs_A) # in case vendors used the sysfs_A label on objects
(typeattributeset sysfs_A_v1 (sysfs sysfs_A))

v2 मैपिंग फ़ाइल (सीआईएल) में:

(typeattributeset sysfs_v2 (sysfs))

वेंडर नीति (सीआईएल) के वर्शन 1 में:

(typeattribute sysfs_A_v1)
(allow  sysfs_A_v1 )
(typeattribute sysfs_v1)
(allow  sysfs_v1 )

वेंडर नीति (सीआईएल) के वर्शन 2 में:

(typeattribute sysfs_v2)
(allow  sysfs_v2 )

उदाहरण का दूसरा वर्शन: पूरी तरह से हटाना (foo टाइप)

v1 से v2 पर अपग्रेड करते समय, प्लैटफ़ॉर्म की नीति में ये चीज़ें होनी चाहिए:

# nothing - we got rid of the type

v1 मैपिंग फ़ाइल (सीआईएल) में:

(type foo) #needed in case vendors used the foo label on objects
(typeattributeset foo_v1 (foo))

v2 मैपिंग फ़ाइल (सीआईएल) में:

# nothing - get rid of it

वेंडर नीति (सीआईएल) के वर्शन 1 में:

(typeattribute foo_v1)
(allow foo )
(typeattribute sysfs_v1)
(allow sysfs_v1 )

वेंडर नीति (सीआईएल) के वर्शन 2 में:

(typeattribute sysfs_v2)
(allow sysfs_v2 )
नई क्लास/अनुमतियां

ऐसा तब होता है, जब प्लैटफ़ॉर्म के अपग्रेड में नीति के ऐसे नए कॉम्पोनेंट शामिल किए जाते हैं जो पिछले वर्शन में मौजूद नहीं होते. उदाहरण के लिए, जब Android ने servicemanager ऑब्जेक्ट मैनेजर जोड़ा, तो जोड़ने, खोजने, और सूची बनाने की अनुमतियां बनाई गईं. servicemanager के साथ रजिस्टर करने वाले वेंडर डेमन को ऐसी अनुमतियां चाहिए थीं जो उपलब्ध नहीं थीं. Android 8.0 में, सिर्फ़ प्लैटफ़ॉर्म की नीति नई क्लास और अनुमतियां जोड़ सकती है.

वेंडर की नीति के तहत बनाए गए या बढ़ाए गए सभी डोमेन को बिना किसी रुकावट के नई क्लास का इस्तेमाल करने की अनुमति देने के लिए, प्लैटफ़ॉर्म की नीति में ऐसा नियम शामिल होना चाहिए जो इस तरह का हो:

allow {domain -coredomain} *:new_class perm;

इसके लिए, सभी इंटरफ़ेस (सार्वजनिक नीति) के टाइप के लिए ऐक्सेस की अनुमति देने वाली नीति की ज़रूरत पड़ सकती है, ताकि यह पक्का किया जा सके कि वेंडर की इमेज का ऐक्सेस मिल जाए. अगर इससे सुरक्षा से जुड़ी ऐसी नीति बनती है जिसे स्वीकार नहीं किया जा सकता (जैसा कि सेवा मैनेजर में किए गए बदलावों की वजह से हो सकता है), तो हो सकता है कि वेंडर को अपग्रेड करने के लिए मजबूर किया जाए.

कक्षा/अनुमतियां हटाई गईं

यह स्थिति तब होती है, जब किसी ऑब्जेक्ट मैनेजर को हटा दिया जाता है. जैसे, ZygoteConnection ऑब्जेक्ट मैनेजर. इससे कोई समस्या नहीं होनी चाहिए. ऑब्जेक्ट मैनेजर क्लास और अनुमतियां, नीति में तब तक बनी रह सकती हैं, जब तक वेंडर वर्शन इसका इस्तेमाल नहीं करता. इसके लिए, मैपिंग फ़ाइल में परिभाषाएं जोड़ी जाती हैं.

नए/फिर से लेबल किए गए टाइप के लिए, वेंडर को पसंद के मुताबिक बनाने की सुविधा

वेंडर नीति बनाने के लिए, वेंडर के नए टाइप की ज़रूरत होती है. ऐसा इसलिए, क्योंकि इनकी मदद से नई प्रोसेस, बाइनरी, डिवाइस, सबसिस्टम, और सेव किए गए डेटा के बारे में बताया जा सकता है. इसलिए, वेंडर के तय किए गए टाइप बनाने की अनुमति देना ज़रूरी है.

डिवाइस पर वेंडर की नीति हमेशा सबसे पुरानी होती है. इसलिए, नीति में सभी तरह के वेंडर को एट्रिब्यूट में अपने-आप बदलने की ज़रूरत नहीं है. प्लैटफ़ॉर्म, वेंडर की नीति में लेबल किए गए किसी भी एट्रिब्यूट पर भरोसा नहीं करता, क्योंकि प्लैटफ़ॉर्म को इसकी जानकारी नहीं होती. हालांकि, प्लैटफ़ॉर्म ऐसे एट्रिब्यूट और सार्वजनिक टाइप उपलब्ध कराएगा जिनका इस्तेमाल, इन टाइप (जैसे, domain, sysfs_type वगैरह) से लेबल किए गए ऑब्जेक्ट के साथ इंटरैक्ट करने के लिए किया जाता है. प्लैटफ़ॉर्म के लिए, इन ऑब्जेक्ट के साथ सही तरीके से इंटरैक्ट करना जारी रखना ज़रूरी है. इसके लिए, एट्रिब्यूट और टाइप को सही तरीके से लागू करना होगा. साथ ही, पसंद के मुताबिक बनाए जा सकने वाले डोमेन (जैसे, init) में खास नियम जोड़ने पड़ सकते हैं.

Android 9 के लिए एट्रिब्यूट में हुए बदलाव

Android 9 पर अपग्रेड करने वाले डिवाइस, इन एट्रिब्यूट का इस्तेमाल कर सकते हैं. हालांकि, Android 9 के साथ लॉन्च होने वाले डिवाइसों को ऐसा नहीं करना चाहिए.

नीति का उल्लंघन करने वाले एट्रिब्यूट

Android 9 में, डोमेन से जुड़े ये एट्रिब्यूट शामिल हैं:

  • data_between_core_and_vendor_violators. vendor और coredomains के बीच के पाथ के हिसाब से फ़ाइलें शेयर न करने की ज़रूरी शर्त का उल्लंघन करने वाले सभी डोमेन के लिए एट्रिब्यूट. प्लैटफ़ॉर्म और वेंडर प्रोसेस को, इंटरैक्ट करने के लिए डिस्क पर मौजूद फ़ाइलों का इस्तेमाल नहीं करना चाहिए (अस्थिर एबीआई). सुझाव:
    • वेंडर कोड में /data/vendor का इस्तेमाल किया जाना चाहिए.
    • सिस्टम में /data/vendor का इस्तेमाल नहीं किया जाना चाहिए.
  • system_executes_vendor_violators. एट्रिब्यूट, उन सभी सिस्टम डोमेन (init और shell domains को छोड़कर) के लिए है जो वेंडर बाइनरी को लागू न करने की ज़रूरी शर्त का उल्लंघन करते हैं. वेंडर बाइनरी को चलाने पर, एपीआई अस्थिर हो जाता है. प्लैटफ़ॉर्म को सीधे तौर पर वेंडर बाइनरी को रन नहीं करना चाहिए. सुझाव:
    • वेंडर बाइनरी पर निर्भरता वाले ऐसे प्लैटफ़ॉर्म, HIDL HAL के पीछे होने चाहिए.

      या

    • जिन coredomains को वेंडर बाइनरी का ऐक्सेस चाहिए उन्हें वेंडर पार्टीशन में ले जाया जाना चाहिए. इससे, वे coredomain नहीं रहेंगे.

ऐसे एट्रिब्यूट जिन पर भरोसा नहीं किया जा सकता

भरोसेमंद नहीं होने वाले ऐसे ऐप्लिकेशन के पास HwBinder सेवाओं का ऐक्सेस नहीं होना चाहिए जो मनमुताबिक कोड होस्ट करते हैं. हालांकि, ऐसे ऐप्लिकेशन के पास उन सेवाओं का ऐक्सेस हो सकता है जिन्हें इन ऐप्लिकेशन से ऐक्सेस करने के लिए पूरी तरह से सुरक्षित माना जाता है. यहां सुरक्षित सेवाओं के बारे में बताया गया है. इसकी दो मुख्य वजहें हैं:

  1. HwBinder सर्वर, क्लाइंट की पुष्टि नहीं करते, क्योंकि फ़िलहाल HIDL, कॉलर के UID की जानकारी ज़ाहिर नहीं करता. भले ही, HIDL ने इस तरह का डेटा ज़ाहिर किया हो, लेकिन कई HwBinder सेवाएं, ऐप्लिकेशन (जैसे, एचएएल) के लेवल से नीचे काम करती हैं या फिर अनुमति के लिए, ऐप्लिकेशन की पहचान पर निर्भर नहीं होनी चाहिए. इसलिए, सुरक्षित रहने के लिए, डिफ़ॉल्ट रूप से यह माना जाता है कि हर HwBinder सेवा, अपने सभी क्लाइंट को सेवा के ऑफ़र किए गए ऑपरेशन करने की अनुमति देती है.
  2. HAL सर्वर (HwBinder सेवाओं का सबसेट) में system/core कॉम्पोनेंट की तुलना में, सुरक्षा से जुड़ी समस्याओं की दर ज़्यादा होती है. साथ ही, इन सर्वर के पास स्टैक की निचली लेयर (पूरी तरह से हार्डवेयर तक) का ऐक्सेस होता है. इसलिए, Android के सुरक्षा मॉडल को बायपास करने के अवसर बढ़ जाते हैं.

सुरक्षित सेवाएं

सुरक्षित सेवाओं में ये शामिल हैं:

  • same_process_hwservice. परिभाषा के मुताबिक, ये सेवाएं क्लाइंट की प्रोसेस में चलती हैं. इसलिए, इनका ऐक्सेस उसी क्लाइंट डोमेन के जैसा होता है जिसमें प्रोसेस चलती है.
  • coredomain_hwservice. इन सेवाओं से, #2 वजह से जुड़े जोखिम नहीं होते.
  • hal_configstore_ISurfaceFlingerConfigs. यह सेवा, खास तौर पर किसी भी डोमेन के इस्तेमाल के लिए डिज़ाइन की गई है.
  • hal_graphics_allocator_hwservice. ये कार्रवाइयां, surfaceflinger बाइंडर सेवा भी करती है. हालांकि, ऐप्लिकेशन को इनका ऐक्सेस नहीं दिया जा सकता.
  • hal_omx_hwservice. यह mediacodec Binder सेवा का HwBinder वर्शन है. ऐप्लिकेशन को इसे ऐक्सेस करने की अनुमति है.
  • hal_codec2_hwservice. यह hal_omx_hwservice का नया वर्शन है.

इस्तेमाल किए जा सकने वाले एट्रिब्यूट

जिन hwservices को सुरक्षित नहीं माना जाता उनमें एट्रिब्यूट untrusted_app_visible_hwservice होता है. उनसे जुड़े एचएएल सर्वर में एट्रिब्यूट untrusted_app_visible_halserver है. Android 9 के साथ लॉन्च होने वाले डिवाइसों के लिए, untrusted एट्रिब्यूट में से किसी एक का इस्तेमाल नहीं किया जाना चाहिए.

सुझाव:

  • भरोसेमंद नहीं होने वाले ऐप्लिकेशन को, सिस्टम की ऐसी सेवा से बात करनी चाहिए जो वेंडर HIDL HAL से बात करती हो. उदाहरण के लिए, ऐप्लिकेशन binderservicedomain से बात कर सकते हैं. इसके बाद, mediaserver (जो binderservicedomain है) hal_graphics_allocator से बात करता है.

    या

  • जिन ऐप्लिकेशन को vendor HALs का सीधा ऐक्सेस चाहिए उनके पास, वेंडर से तय किया गया अपना sepolicy डोमेन होना चाहिए.

फ़ाइल एट्रिब्यूट के टेस्ट

Android 9 में बिल्ड टाइम टेस्ट शामिल हैं. इनसे यह पक्का किया जाता है कि खास जगहों पर मौजूद सभी फ़ाइलों में सही एट्रिब्यूट हों. जैसे, sysfs में मौजूद सभी फ़ाइलों में ज़रूरी sysfs_type एट्रिब्यूट होना.

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

प्लैटफ़ॉर्म की सार्वजनिक नीति, Android 8.0 के आर्किटेक्चर मॉडल के मुताबिक है. इसमें, वर्शन 1 और वर्शन 2 की प्लैटफ़ॉर्म नीतियों को शामिल नहीं किया गया है. वेंडर को प्लैटफ़ॉर्म की नीति का एक सबसेट दिखता है. इसमें इस्तेमाल किए जा सकने वाले टाइप और एट्रिब्यूट के साथ-साथ, उन टाइप और एट्रिब्यूट के लिए नियम होते हैं. ये नियम, वेंडर की नीति (यानी vendor_sepolicy.cil) का हिस्सा बन जाते हैं.

वेंडर की जनरेट की गई नीति में, टाइप और नियम अपने-आप attribute_vN में बदल जाते हैं. ऐसा इसलिए होता है, ताकि प्लैटफ़ॉर्म के सभी टाइप, वर्शन वाले एट्रिब्यूट हों. हालांकि, एट्रिब्यूट के वर्शन नहीं होते. प्लैटफ़ॉर्म, अपने दिए गए कॉन्क्रीट टाइप को सही एट्रिब्यूट में मैप करने के लिए ज़िम्मेदार होता है. इससे यह पक्का होता है कि वेंडर की नीति लागू होती रहे और किसी खास वर्शन के लिए दिए गए नियम शामिल हों. प्लैटफ़ॉर्म की सार्वजनिक नीति और वेंडर नीति का कॉम्बिनेशन, Android 8.0 के आर्किटेक्चर मॉडल के लक्ष्य को पूरा करता है. इस लक्ष्य के तहत, इंडिपेंडेंट प्लैटफ़ॉर्म और वेंडर के लिए, बिल्ड करने की अनुमति दी जाती है.

एट्रिब्यूट चेन पर मैप करना

नीति के वर्शन पर मैप करने के लिए एट्रिब्यूट का इस्तेमाल करने पर, टाइप किसी एट्रिब्यूट या कई एट्रिब्यूट पर मैप होता है. इससे यह पक्का होता है कि टाइप के साथ लेबल किए गए ऑब्जेक्ट, उनके पिछले टाइप से जुड़े एट्रिब्यूट के ज़रिए ऐक्सेस किए जा सकते हैं.

नीति लिखने वाले व्यक्ति से वर्शन की जानकारी छिपाने का लक्ष्य बनाए रखने का मतलब है कि वर्शन वाले एट्रिब्यूट अपने-आप जनरेट हो जाएं और उन्हें सही टाइप के लिए असाइन कर दिया जाए. स्टैटिक टाइप के सामान्य मामले में, यह आसान है: type_foo, type_foo_v1 पर मैप करता है.

sysfssysfs_A या mediaserveraudioserver जैसे ऑब्जेक्ट लेबल में बदलाव करने के लिए, यह मैपिंग बनाना आसान नहीं है. इस बारे में ऊपर दिए गए उदाहरणों में बताया गया है. प्लैटफ़ॉर्म की नीति को मैनेज करने वाले लोगों को यह तय करना होगा कि ऑब्जेक्ट के ट्रांज़िशन पॉइंट पर मैपिंग कैसे बनाई जाए. इसके लिए, उन्हें ऑब्जेक्ट और उनके असाइन किए गए लेबल के बीच के संबंध को समझना होगा. साथ ही, यह तय करना होगा कि यह कब होता है. पुराने सिस्टम के साथ काम करने की सुविधा के लिए, इस मुश्किल को प्लैटफ़ॉर्म के हिसाब से मैनेज करना होगा. यह एक ऐसा ही पार्टिशन है जिसे अपग्रेड किया जा सकता है.

वर्शन के अपग्रेड

आसानी से समझने के लिए, Android प्लैटफ़ॉर्म कोई नई रिलीज़ ब्रैंच बनाने पर, sepolicy का वर्शन रिलीज़ करता है. जैसा कि ऊपर बताया गया है, वर्शन नंबर PLATFORM_SEPOLICY_VERSION में होता है और यह MM.nn फ़ॉर्मैट में होता है. इसमें MM, SDK टूल की वैल्यू से जुड़ा होता है और nn, /platform/system/sepolicy. में रखी गई निजी वैल्यू होती है. उदाहरण के लिए, KitKat के लिए 19.0, Lollipop के लिए 21.0, Lollipop-MR1 के लिए 22.0, Marshmallow के लिए 23.0, Nougat के लिए 24.0, Nougat-MR1 के लिए 25.0, Oreo के लिए 26.0, Oreo-MR1 के लिए 27.0, और Android 9 के लिए 28.0. यूपीर्व हमेशा पूरी संख्या नहीं होते. उदाहरण के लिए, अगर किसी वर्शन में एमआर बंप करने के लिए, system/sepolicy/public में ऐसा बदलाव करना ज़रूरी है जो काम न करे, लेकिन एपीआई बंप न करना ज़रूरी हो, तो sepolicy का वह वर्शन यह हो सकता है: vN.1. डेवलपमेंट ब्रैंच में मौजूद वर्शन, डिवाइसों में कभी भी इस्तेमाल नहीं किया जा सकता 10000.0.

Android, अपडेट करते समय सबसे पुराने वर्शन को बंद कर सकता है. किसी वर्शन को कब बंद करना है, इस बारे में जानकारी पाने के लिए Android, वेंडर की नीतियों के तहत चल रहे उन डिवाइसों की संख्या इकट्ठा कर सकता है जिन पर Android का वह वर्शन चल रहा है और जिन्हें अब भी प्लैटफ़ॉर्म के मुख्य अपडेट मिल रहे हैं. अगर यह संख्या तय सीमा से कम है, तो उस वर्शन का इस्तेमाल बंद कर दिया जाता है.

एक से ज़्यादा एट्रिब्यूट की वजह से परफ़ॉर्मेंस पर असर

जैसा कि https://github.com/SELinuxProject/cil/issues/9 में बताया गया है, किसी टाइप के लिए असाइन किए गए कई एट्रिब्यूट की वजह से, नीति के कैश मेमोरी में मौजूद न होने पर परफ़ॉर्मेंस से जुड़ी समस्याएं आती हैं.

यह पुष्टि की गई थी कि यह Android में एक समस्या है. इसलिए, नीति कंपाइलर की ओर से नीति में जोड़े गए एट्रिब्यूट को हटाने के लिए, Android 8.0 में बदलाव किए गए. साथ ही, इस्तेमाल न किए गए एट्रिब्यूट को भी हटाया गया. इन बदलावों से, परफ़ॉर्मेंस में आई गिरावट को ठीक किया गया है.

system_ext की सार्वजनिक और प्रॉडक्ट की सार्वजनिक नीति

Android 11 से, system_ext और product सेक्शन को, वेंडर सेक्शन में अपने तय किए गए पब्लिक टाइप एक्सपोर्ट करने की अनुमति है. प्लैटफ़ॉर्म की सार्वजनिक नीति की तरह, वेंडर उन टाइप और नियमों का इस्तेमाल करता है जो वर्शन वाले एट्रिब्यूट में अपने-आप ट्रांसलेट हो जाते हैं. उदाहरण के लिए, type से type_N में, जहां N उस प्लैटफ़ॉर्म का वर्शन है जिसके लिए वेंडर का पार्टीशन बनाया गया है.

जब system_ext और product पार्टिशन, एक ही प्लैटफ़ॉर्म वर्शन N पर आधारित होते हैं, तो बिल्ड सिस्टम system_ext/etc/selinux/mapping/N.cil और product/etc/selinux/mapping/N.cil के लिए बुनियादी मैपिंग फ़ाइलें जनरेट करता है. इनमें type से type_N तक की आइडेंटिटी मैपिंग होती हैं. वेंडर, वर्शन वाले एट्रिब्यूट type_N की मदद से type को ऐक्सेस कर सकता है.

अगर सिर्फ़ system_ext और product पार्टिशन को अपडेट किया जाता है, जैसे कि N से N+1 (या उसके बाद) पर, जबकि वेंडर N पर ही रहता है, तो हो सकता है कि वेंडर के पास system_ext और product पार्टिशन के टाइप का ऐक्सेस न रहे. डेटा को अलग-अलग हिस्सों में बांटने से रोकने के लिए, system_ext और product सेक्शन में, कंक्रीट टाइप से type_N एट्रिब्यूट में मैपिंग फ़ाइलें उपलब्ध कराई जानी चाहिए. अगर कोई पार्टनर N वेंडर के साथ N+1 (या उसके बाद के वर्शन)system_ext और product पार्टीशन के लिए काम करना चाहता है, तो उसे मैपिंग फ़ाइलों को मैनेज करना होगा.

ऐसा करने के लिए, पार्टनर को:

  1. जनरेट की गई बेस मैपिंग फ़ाइलों को N system_ext और product सेक्शन से उनके सोर्स ट्री में कॉपी करें.
  2. ज़रूरत के हिसाब से मैपिंग फ़ाइलों में बदलाव करें.
  3. N+1 (या उसके बाद के वर्शन) system_ext और product वाले पार्टीशन में, मैपिंग फ़ाइलें इंस्टॉल करें.

उदाहरण के लिए, मान लें कि N system_ext में foo_type नाम का एक सार्वजनिक टाइप है. इसके बाद, N system_ext पार्टीशन में system_ext/etc/selinux/mapping/N.cil इस तरह दिखेगा:

(typeattributeset foo_type_N (foo_type))
(expandtypeattribute foo_type_N true)
(typeattribute foo_type_N)

अगर bar_type को N+1 system_ext में जोड़ा गया है और N वेंडर के लिए bar_type को foo_type पर मैप किया जाना चाहिए, तो N.cil को

(typeattributeset foo_type_N (foo_type))

to

(typeattributeset foo_type_N (foo_type bar_type))

इसके बाद, N+1 system_ext के पार्टीशन में इंस्टॉल किया जाता है. N वेंडर, N+1 system_ext के foo_type और bar_type को ऐक्सेस करना जारी रख सकता है.

SELinux कॉन्टेक्स्ट लेबल करना

प्लैटफ़ॉर्म और वेंडर के सेक्योरिटी पॉलिसी के बीच अंतर करने के लिए, सिस्टम SELinux कॉन्टेक्स्ट फ़ाइलों को अलग-अलग बनाता है, ताकि उन्हें अलग रखा जा सके.

फ़ाइल के कॉन्टेक्स्ट

Android 8.0 में file_contexts के लिए ये बदलाव किए गए हैं:

  • डिवाइस के बूट होने के दौरान, कॉम्पाइल करने में लगने वाले समय को कम करने के लिए, file_contexts को बाइनरी फ़ॉर्मैट में उपलब्ध नहीं कराया जाता. इसके बजाय, ये रेगुलर एक्सप्रेशन वाली टेक्स्ट फ़ाइलें होती हैं, जिन्हें पढ़ा जा सकता है. जैसे, {property, service}_contexts (जैसा कि वे 7.0 से पहले थीं).
  • file_contexts को दो फ़ाइलों में बांटा गया है:
    • plat_file_contexts
      • Android प्लैटफ़ॉर्म file_context, जिसमें डिवाइस के हिसाब से लेबल नहीं हैं. हालांकि, /vendor पार्टीशन के कुछ हिस्सों को लेबल करना ज़रूरी है, ताकि sepolicy फ़ाइलों के ठीक से काम करने की पुष्टि की जा सके.
      • यह ज़रूरी है कि यह डिवाइस पर /system/etc/selinux/plat_file_contexts पर system पार्टीशन में मौजूद हो और इसे init के साथ-साथ वेंडर file_context के साथ शुरू में लोड किया जाए.
    • vendor_file_contexts
      • डिवाइस के हिसाब से file_context, जिसे डिवाइस की Boardconfig.mk फ़ाइलों में मौजूद BOARD_SEPOLICY_DIRS से मिली डायरेक्ट्री में मिले file_contexts को जोड़कर बनाया गया है.
      • इसे vendor सेगमेंट में /vendor/etc/selinux/vendor_file_contexts पर इंस्टॉल किया जाना चाहिए. साथ ही, इसे file_context प्लैटफ़ॉर्म के साथ शुरू में init से लोड किया जाना चाहिए.

प्रॉपर्टी के कॉन्टेक्स्ट

Android 8.0 में, property_contexts को दो फ़ाइलों में बांटा गया है:

  • plat_property_contexts
    • Android प्लैटफ़ॉर्म property_context, जिसमें डिवाइस के हिसाब से कोई लेबल नहीं है.
    • यह /system/etc/selinux/plat_property_contexts पर system पार्टीशन में मौजूद होना चाहिए और इसे init के साथ-साथ, वेंडर property_contexts के साथ शुरू में लोड किया जाना चाहिए.
  • vendor_property_contexts
    • डिवाइस के हिसाब से property_context, डिवाइस की Boardconfig.mk फ़ाइलों में मौजूद BOARD_SEPOLICY_DIRS से मिली डायरेक्ट्री में मिले property_contexts को जोड़कर बनाया गया है.
    • यह /vendor/etc/selinux/vendor_property_contexts पर vendor सेक्शन में मौजूद होना चाहिए और इसे init के साथ-साथ प्लैटफ़ॉर्म property_context के साथ शुरू में लोड किया जाना चाहिए

सेवा के संदर्भ

Android 8.0 में, service_contexts को इन फ़ाइलों के बीच बांटा गया है:

  • plat_service_contexts
    • servicemanager के लिए, Android प्लैटफ़ॉर्म के हिसाब से service_context. service_context में, डिवाइस के हिसाब से कोई लेबल नहीं है.
    • यह /system/etc/selinux/plat_service_contexts पर system पार्टीशन में मौजूद होना चाहिए. साथ ही, इसे service_contexts वेंडर के साथ शुरू में servicemanager से लोड किया जाना चाहिए.
  • vendor_service_contexts
    • डिवाइस के हिसाब से service_context, डिवाइस की Boardconfig.mk फ़ाइलों में मौजूद BOARD_SEPOLICY_DIRS से मिली डायरेक्ट्री में मिले service_contexts को जोड़कर बनाया जाता है.
    • यह /vendor/etc/selinux/vendor_service_contexts पर vendor सेक्शन में मौजूद होना चाहिए. साथ ही, इसे servicemanager के साथ प्लैटफ़ॉर्म service_contexts के शुरू होने पर लोड किया जाना चाहिए.
    • servicemanager, बूट के समय इस फ़ाइल को ढूंढता है. हालांकि, पूरी तरह से नियमों का पालन करने वाले TREBLE डिवाइस के लिए, vendor_service_contexts का मौजूद होना ज़रूरी नहीं है. ऐसा इसलिए है, क्योंकि vendor और system प्रोसेस के बीच होने वाले सभी इंटरैक्शन के लिए, hwservicemanager/hwbinder का इस्तेमाल करना ज़रूरी है.
  • plat_hwservice_contexts
    • hwservicemanager के लिए, Android प्लैटफ़ॉर्म hwservice_context, जिसमें डिवाइस के हिसाब से लेबल नहीं हैं.
    • यह /system/etc/selinux/plat_hwservice_contexts पर system पार्टीशन में होना चाहिए और शुरू में vendor_hwservice_contexts के साथ hwservicemanager से लोड किया जाना चाहिए.
  • vendor_hwservice_contexts
    • डिवाइस के हिसाब से hwservice_context, डिवाइस की Boardconfig.mk फ़ाइलों में मौजूद BOARD_SEPOLICY_DIRS से मिली डायरेक्ट्री में मिले hwservice_contexts को जोड़कर बनाया जाता है.
    • यह /vendor/etc/selinux/vendor_hwservice_contexts पर vendor सेक्शन में होना चाहिए और शुरू में plat_service_contexts के साथ hwservicemanager से लोड किया जाना चाहिए.
  • vndservice_contexts
    • डिवाइस के हिसाब से service_context, जो डिवाइस के Boardconfig.mk में BOARD_SEPOLICY_DIRS से दिखाए गए डायरेक्ट्री में मिले vndservice_contexts को जोड़कर बनाया गया vndservicemanager है.
    • यह फ़ाइल, /vendor/etc/selinux/vndservice_contexts के समय vendor पार्टीशन में होनी चाहिए और शुरू में vndservicemanager से लोड होनी चाहिए.

Seapp कॉन्टेक्स्ट

Android 8.0 में, seapp_contexts को दो फ़ाइलों में बांटा गया है:

  • plat_seapp_contexts
    • Android प्लैटफ़ॉर्म seapp_context, जिसमें डिवाइस के हिसाब से कोई बदलाव नहीं किया गया है.
    • /system/etc/selinux/plat_seapp_contexts. पर, system पार्टीशन में मौजूद होना चाहिए
  • vendor_seapp_contexts
    • डिवाइस के हिसाब से, प्लैटफ़ॉर्म seapp_context के लिए बनाया गया एक्सटेंशन. इसे, डिवाइस की Boardconfig.mk फ़ाइलों में BOARD_SEPOLICY_DIRS से दिखाए गए डायरेक्ट्री में मिले seapp_contexts को जोड़कर बनाया गया है.
    • यह /vendor/etc/selinux/vendor_seapp_contexts पर, vendor पार्टीशन में होना चाहिए.

एमएसी की अनुमतियां

Android 8.0 में, mac_permissions.xml को दो फ़ाइलों में बांटा गया है:

  • प्लैटफ़ॉर्म mac_permissions.xml
    • Android प्लैटफ़ॉर्म mac_permissions.xml, जिसमें डिवाइस के हिसाब से कोई बदलाव नहीं किया गया है.
    • /system/etc/selinux/. पर, system पार्टीशन में मौजूद होना चाहिए
  • नॉन-प्लैटफ़ॉर्म mac_permissions.xml
    • डिवाइस के हिसाब से, प्लैटफ़ॉर्म के लिए बने mac_permissions.xml एक्सटेंशन को mac_permissions.xml से बनाया गया है. यह डिवाइस की Boardconfig.mk फ़ाइलों में, BOARD_SEPOLICY_DIRS से बताई गई डायरेक्ट्री में मिलता है.
    • /vendor/etc/selinux/. पर, vendor पार्टीशन में मौजूद होना चाहिए