SELinux को डिफ़ॉल्ट रूप से अनुमति न देने के लिए सेट अप किया जाता है. इसका मतलब है कि कर्नल में मौजूद हर ऐक्सेस के लिए, नीति के तहत साफ़ तौर पर अनुमति दी जानी चाहिए. इसका मतलब है कि नीति से जुड़ी फ़ाइल में नियमों, टाइप, क्लास, अनुमतियों वगैरह के बारे में ज़्यादा जानकारी होती है. इस दस्तावेज़ में SELinux के बारे में पूरी जानकारी नहीं दी गई है. हालाँकि, नए Android डिवाइसों को चालू करते समय, नीति के नियमों को लिखने का तरीका समझना ज़रूरी है. SELinux के बारे में पहले से ही काफ़ी जानकारी उपलब्ध है. सुझाए गए संसाधनों के लिए, ज़रूरी दस्तावेज़ देखें.
मुख्य फ़ाइलें
SELinux को चालू करने के लिए, Android के नए कर्नेल को इंटिग्रेट करें. इसके बाद, system/sepolicy डायरेक्ट्री में मौजूद फ़ाइलों को शामिल करें. कंपाइल करने के बाद, इन फ़ाइलों में SELinux कर्नल की सुरक्षा नीति शामिल होती है. साथ ही, इनमें अपस्ट्रीम Android ऑपरेटिंग सिस्टम भी शामिल होता है.
आम तौर पर, आपको system/sepolicy
फ़ाइलों में सीधे तौर पर बदलाव नहीं करना चाहिए. इसके बजाय, /device/manufacturer/device-name/sepolicy
डायरेक्ट्री में डिवाइस के हिसाब से नीति की फ़ाइलें जोड़ें या उनमें बदलाव करें. Android 8.0 और इसके बाद के वर्शन में, इन फ़ाइलों में किए गए बदलावों का असर सिर्फ़ वेंडर डायरेक्ट्री में मौजूद नीति पर पड़ना चाहिए. Android 8.0 और इसके बाद के वर्शन में, सार्वजनिक सेपॉलिसी को अलग करने के बारे में ज़्यादा जानने के लिए, Android 8.0 और इसके बाद के वर्शन में SEPolicy को पसंद के मुताबिक बनाना लेख पढ़ें. Android के वर्शन से कोई फ़र्क़ नहीं पड़ता, आपको अब भी इन फ़ाइलों में बदलाव करना होगा:
नीति से जुड़ी फ़ाइलें
*.te
से खत्म होने वाली फ़ाइलें, SELinux नीति की सोर्स फ़ाइलें होती हैं. ये डोमेन और उनके लेबल तय करती हैं. आपको /device/manufacturer/device-name/sepolicy
में नई नीति फ़ाइलें बनानी पड़ सकती हैं. हालांकि, जहां भी हो सके वहां आपको मौजूदा फ़ाइलों को अपडेट करना चाहिए.
कॉन्टेक्स्ट फ़ाइलें
कॉन्टेक्स्ट फ़ाइलों में, ऑब्जेक्ट के लिए लेबल तय किए जाते हैं.
file_contexts
फ़ाइलों को लेबल असाइन करता है. इसका इस्तेमाल अलग-अलग यूज़रस्पेस कॉम्पोनेंट करते हैं. नई नीतियां बनाते समय, इस फ़ाइल को बनाएं या अपडेट करें, ताकि फ़ाइलों को नए लेबल असाइन किए जा सकें. नएfile_contexts
लागू करने के लिए, फ़ाइल सिस्टम इमेज को फिर से बनाएं या जिस फ़ाइल का लेबल बदलना है उस परrestorecon
चलाएं. अपग्रेड करने पर,file_contexts
में किए गए बदलाव, सिस्टम और उपयोगकर्ता डेटा के पार्टीशन पर अपने-आप लागू हो जाते हैं. ऐसा अपग्रेड के दौरान होता है. पार्टिशन को रीड-राइट मोड में माउंट करने के बाद, init.board.rc फ़ाइल मेंrestorecon_recursive
कॉल जोड़कर, अन्य पार्टिशन में अपग्रेड करने पर बदलाव अपने-आप लागू हो सकते हैं.genfs_contexts
, फ़ाइल सिस्टम को लेबल असाइन करता है. जैसे,proc
याvfat
, जो एक्सटेंडेड एट्रिब्यूट के साथ काम नहीं करते. इस कॉन्फ़िगरेशन को कर्नेल नीति के हिस्से के तौर पर लोड किया जाता है. हालांकि, हो सकता है कि इन-कोर इनोड के लिए बदलाव लागू न हों. इसके लिए, डिवाइस को रीबूट करना पड़ सकता है या फ़ाइल सिस्टम को अनमाउंट करके फिर से माउंट करना पड़ सकता है, ताकि बदलाव पूरी तरह से लागू हो सके. कुछ खास माउंट को भी कुछ खास लेबल असाइन किए जा सकते हैं. जैसे,vfat
विकल्प का इस्तेमाल करकेcontext=mount
.property_contexts
, Android सिस्टम प्रॉपर्टी को लेबल असाइन करता है, ताकि यह कंट्रोल किया जा सके कि कौनसी प्रोसेस उन्हें सेट कर सकती हैं. इस कॉन्फ़िगरेशन को स्टार्टअप के दौरानinit
प्रोसेस पढ़ती है.service_contexts
, Android बाइंडर सेवाओं को लेबल असाइन करता है, ताकि यह कंट्रोल किया जा सके कि कौनसी प्रोसेस, सेवा के लिए बाइंडर रेफ़रंस जोड़ (रजिस्टर) सकती है और ढूंढ (लुकअप) सकती है. इस कॉन्फ़िगरेशन को स्टार्टअप के दौरानservicemanager
प्रोसेस पढ़ती है.seapp_contexts
, ऐप्लिकेशन प्रोसेस और/data/data
डायरेक्ट्री को लेबल असाइन करता है. इस कॉन्फ़िगरेशन को हर ऐप्लिकेशन लॉन्च परzygote
प्रोसेस और स्टार्टअप के दौरानinstalld
पढ़ता है.mac_permissions.xml
, ऐप्लिकेशन कोseinfo
टैग असाइन करता है. ऐसा उनके हस्ताक्षर और पैकेज के नाम के आधार पर किया जाता है. हालांकि, पैकेज का नाम देना ज़रूरी नहीं है. इसके बाद,seinfo
टैग का इस्तेमालseapp_contexts
फ़ाइल में कुंजी के तौर पर किया जा सकता है. इससे उसseinfo
टैग वाले सभी ऐप्लिकेशन को कोई खास लेबल असाइन किया जा सकता है. इस कॉन्फ़िगरेशन को स्टार्टअप के दौरानsystem_server
पढ़ता है.keystore2_key_contexts
, Keystore 2 के नेमस्पेस को लेबल असाइन करता है. इन नेमस्पेस कोkeystore2
डेमॉन लागू करता है. Keystore हमेशा से यूआईडी/एआईडी पर आधारित नेमस्पेस उपलब्ध कराता है. Keystore 2, sepolicy में तय किए गए नेमस्पेस को भी लागू करता है. इस फ़ाइल के फ़ॉर्मैट और कन्वेंशनल के बारे में ज़्यादा जानकारी यहां दी गई है.
BoardConfig.mk मेकफ़ाइल
नीति और कॉन्टेक्स्ट फ़ाइलों में बदलाव करने या उन्हें जोड़ने के बाद, अपनी /device/manufacturer/device-name/BoardConfig.mk
मेकफ़ाइल को अपडेट करें. इससे sepolicy
सबडायरेक्ट्री और हर नई नीति फ़ाइल का रेफ़रंस दिया जा सकेगा.
BOARD_SEPOLICY
वैरिएबल के बारे में ज़्यादा जानकारी के लिए,
system/sepolicy/README
फ़ाइल देखें.
BOARD_SEPOLICY_DIRS += \ <root>/device/manufacturer/device-name/sepolicy BOARD_SEPOLICY_UNION += \ genfs_contexts \ file_contexts \ sepolicy.te
फिर से बनाने के बाद, आपके डिवाइस पर SELinux चालू हो जाता है. अब आपके पास दो विकल्प हैं. पहला, कस्टम बनाने की सुविधा में बताए गए तरीके से, Android ऑपरेटिंग सिस्टम में अपने हिसाब से बदलाव करने के लिए, SELinux की नीतियों को पसंद के मुताबिक बनाएं. दूसरा, पुष्टि करना में बताए गए तरीके से, अपने मौजूदा सेटअप की पुष्टि करें.
नई नीति की फ़ाइलें और BoardConfig.mk अपडेट लागू होने पर, नीति की नई सेटिंग अपने-आप फ़ाइनल कर्नल नीति की फ़ाइल में शामिल हो जाती हैं. डिवाइस पर sepolicy कैसे बनाया जाता है, इस बारे में ज़्यादा जानने के लिए, sepolicy बनाना लेख पढ़ें.
लागू करना
SELinux का इस्तेमाल शुरू करने के लिए:
- कर्नेल में SELinux चालू करें:
CONFIG_SECURITY_SELINUX=y
- kernel_cmdline या bootconfig पैरामीटर में बदलाव करें, ताकि:
याBOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
यह सिर्फ़ डिवाइस के लिए नीति को शुरुआती तौर पर डेवलप करने के लिए है. बूटस्ट्रैप की शुरुआती नीति लागू करने के बाद, इस पैरामीटर को हटा दें, ताकि आपका डिवाइस नीति लागू कर सके या सीटीएस पास न कर सके.BOARD_BOOTCONFIG := androidboot.selinux=permissive
- सिस्टम को नीति लागू न करने वाले मोड में बूट करें और देखें कि बूट करने पर किन चीज़ों को अनुमति नहीं मिली:
Ubuntu 14.04 या इसके बाद के वर्शन पर: Ubuntu 12.04 पर:adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy
adb pull /sys/fs/selinux/policy adb logcat -b all | audit2allow -p policy
- ऐसे जवाबों की समीक्षा करें जिनमें
init: Warning! Service name needs a SELinux domain defined; please fix!
निर्देशों और टूल के लिए, पुष्टि करना देखें जैसी चेतावनियां शामिल हों. - उन डिवाइसों और अन्य नई फ़ाइलों की पहचान करना जिन्हें लेबल करने की ज़रूरत है.
- अपने ऑब्जेक्ट के लिए मौजूदा या नए लेबल का इस्तेमाल करें.
*_contexts
फ़ाइलों को देखकर पता लगाएं कि पहले चीज़ों को कैसे लेबल किया गया था. इसके बाद, लेबल के मतलब के बारे में जानकारी का इस्तेमाल करके, नया लेबल असाइन करें. आमतौर पर, यह एक ऐसा मौजूदा लेबल होता है जो नीति के मुताबिक होता है. हालांकि, कभी-कभी नए लेबल की ज़रूरत होती है. साथ ही, उस लेबल को ऐक्सेस करने के नियमों की भी ज़रूरत होती है. अपने लेबल को सही कॉन्टेक्स्ट फ़ाइलों में जोड़ें. - उन डोमेन/प्रोसेस की पहचान करें जिनके लिए अलग सुरक्षा डोमेन होने चाहिए.
आपको हर एक के लिए, नई नीति लिखनी पड़ सकती है.
init
से शुरू होने वाली सभी सेवाओं के लिए, उदाहरण के लिए, उनके पास खुद का होना चाहिए. यहां दी गई कमांड से, उन सेवाओं के बारे में पता चलता है जो अब भी चल रही हैं. हालांकि, सभी सेवाओं के लिए ऐसा करना ज़रूरी है:
adb shell su -c ps -Z | grep init
adb shell su -c dmesg | grep 'avc: '
init.device.rc
की समीक्षा करके, ऐसे डोमेन की पहचान करें जिनमें डोमेन टाइप नहीं है. उन्हें डेवलपमेंट प्रोसेस के शुरुआती चरण में ही डोमेन दें, ताकिinit
में नियम जोड़ने से बचा जा सके. इसके अलावा,init
के ऐक्सेस को उनकी नीति में शामिल ऐक्सेस के साथ भ्रमित होने से भी बचाया जा सके.BOARD_CONFIG.mk
वैरिएबल इस्तेमाल करने के लिए,BOARD_SEPOLICY_*
सेट अप करें. इसे सेट अप करने के बारे में ज़्यादा जानने के लिए,system/sepolicy
में README देखें.- init.device.rc और fstab.device फ़ाइल की जांच करें. साथ ही, पक्का करें कि
mount
का हर इस्तेमाल, सही तरीके से लेबल किए गए फ़ाइल सिस्टम से मेल खाता हो याcontext= mount
विकल्प दिया गया हो. - हर अस्वीकार किए गए अनुरोध की समीक्षा करें और हर अनुरोध को सही तरीके से हैंडल करने के लिए, SELinux नीति बनाएं. पसंद के मुताबिक बनाना लेख में दिए गए उदाहरण देखें.
आपको AOSP में मौजूद नीतियों से शुरुआत करनी चाहिए. इसके बाद, अपनी पसंद के मुताबिक बदलाव करने के लिए, इन नीतियों को बेहतर बनाना चाहिए. नीति की रणनीति और इनमें से कुछ चरणों के बारे में ज़्यादा जानने के लिए, SELinux की नीति लिखना लेख पढ़ें.
इस्तेमाल के उदाहरण
अपना सॉफ़्टवेयर और उससे जुड़ी SELinux नीतियां बनाते समय, इन खास उदाहरणों पर ध्यान दें:
सिंबॉलिक लिंक: सिंबॉलिक लिंक, फ़ाइलों के तौर पर दिखते हैं. इसलिए, इन्हें अक्सर फ़ाइलों के तौर पर पढ़ा जाता है. इससे फ़ायदा उठाया जा सकता है. उदाहरण के लिए, कुछ खास कॉम्पोनेंट, जैसे कि init
, कुछ फ़ाइलों की अनुमतियों को बदल देते हैं. कभी-कभी, ये अनुमतियां बहुत ज़्यादा खुली होती हैं.
इसके बाद, हमलावर उन फ़ाइलों को ऐसे सिम्लिंक से बदल सकते हैं जिन्हें वे कंट्रोल करते हैं. इससे हमलावर को किसी भी फ़ाइल को बदलने की अनुमति मिल जाती है. हालांकि, अगर आपको पता है कि आपका ऐप्लिकेशन कभी भी सिमलंक को ट्रैवर्स नहीं करता है, तो SELinux की मदद से ऐसा करने से रोका जा सकता है.
सिस्टम फ़ाइलें: सिस्टम फ़ाइलों की उस क्लास पर विचार करें जिसे सिर्फ़ सिस्टम सर्वर से बदला जाना चाहिए. हालांकि, netd
, init
, और vold
रूट के तौर पर काम करते हैं. इसलिए, वे उन सिस्टम फ़ाइलों को ऐक्सेस कर सकते हैं. इसलिए, अगर netd
से समझौता किया गया, तो यह उन फ़ाइलों और सिस्टम सर्वर को भी खतरे में डाल सकता है.
SELinux की मदद से, इन फ़ाइलों को सिस्टम सर्वर डेटा फ़ाइलों के तौर पर पहचाना जा सकता है.
इसलिए, सिर्फ़ सिस्टम सर्वर के पास ही उन्हें पढ़ने/लिखने का ऐक्सेस होता है.
अगर netd
से समझौता किया गया हो, तब भी यह सिस्टम सर्वर डोमेन पर स्विच नहीं कर सकता. साथ ही, यह उन सिस्टम फ़ाइलों को ऐक्सेस नहीं कर सकता, भले ही यह रूट के तौर पर काम करता हो.
ऐप्लिकेशन का डेटा: एक और उदाहरण, फ़ंक्शन की उस क्लास का है जिसे रूट के तौर पर चलाना ज़रूरी है, लेकिन उसे ऐप्लिकेशन के डेटा को ऐक्सेस करने की अनुमति नहीं मिलनी चाहिए. यह बहुत काम का है, क्योंकि इससे कई तरह के दावे किए जा सकते हैं. जैसे, ऐप्लिकेशन के डेटा से जुड़े कुछ डोमेन को इंटरनेट ऐक्सेस करने से रोका जा सकता है.
setattr: chmod
और chown
जैसी कमांड के लिए, उन फ़ाइलों के सेट की पहचान की जा सकती है जहां जुड़ा हुआ डोमेन setattr
कर सकता है. इसके अलावा, किसी भी अन्य फ़ाइल में बदलाव करने पर पाबंदी लगाई जा सकती है. भले ही, वह बदलाव रूट ऐक्सेस वाले उपयोगकर्ता ने किया हो. इसलिए, कोई ऐप्लिकेशन chmod
और chown
को app_data_files
के तौर पर लेबल किए गए लोगों के ख़िलाफ़ इस्तेमाल कर सकता है, लेकिन shell_data_files
या system_data_files
के ख़िलाफ़ नहीं.