SELinux ตั้งค่าเป็นปฏิเสธโดยค่าเริ่มต้น ซึ่งหมายความว่าการเข้าถึงทุกครั้งที่ SELinux มี Hook ในเคอร์เนลจะต้องได้รับอนุญาตอย่างชัดเจนจากนโยบาย ซึ่งหมายความว่าไฟล์นโยบายประกอบด้วยข้อมูลจำนวนมากเกี่ยวกับ กฎ ประเภท คลาส สิทธิ์ และอื่นๆ การพิจารณา SELinux อย่างเต็มรูปแบบ อยู่นอกขอบเขตของเอกสารนี้ แต่การทำความเข้าใจวิธีเขียน กฎนโยบายเป็นสิ่งจำเป็นในตอนนี้เมื่อนำอุปกรณ์ Android ใหม่มาใช้ มีข้อมูลมากมายเกี่ยวกับ SELinux อยู่แล้ว ดูแหล่งข้อมูลที่แนะนำได้ในเอกสารประกอบ
ไฟล์สำคัญ
หากต้องการเปิดใช้ SELinux ให้ผสานรวมเคอร์เนล Android ล่าสุด แล้วรวมไฟล์ที่อยู่ในไดเรกทอรี system/sepolicy เมื่อคอมไพล์แล้ว ไฟล์เหล่านั้นจะประกอบกันเป็นนโยบายความปลอดภัยของเคอร์เนล SELinux และครอบคลุมระบบปฏิบัติการ Android ต้นทาง
โดยทั่วไปแล้ว คุณไม่ควรแก้ไขไฟล์ system/sepolicy โดยตรง แต่ให้เพิ่มหรือแก้ไขไฟล์นโยบายเฉพาะอุปกรณ์ของคุณเองในไดเรกทอรี
/device/manufacturer/device-name/sepolicy
แทน ใน Android 8.0 ขึ้นไป การเปลี่ยนแปลงที่คุณทำกับไฟล์เหล่านี้ควร
ส่งผลต่อนโยบายในไดเรกทอรีของผู้ให้บริการเท่านั้น ดูรายละเอียดเพิ่มเติมเกี่ยวกับการแยก
sepolicy สาธารณะใน Android 8.0 ขึ้นไปได้ที่
การปรับแต่ง SEPolicy ใน Android
8.0 ขึ้นไป ไม่ว่าจะเป็น Android เวอร์ชันใด คุณก็ยังคงแก้ไขไฟล์ต่อไปนี้ได้
ไฟล์นโยบาย
ไฟล์ที่ลงท้ายด้วย *.te คือไฟล์ต้นฉบับของนโยบาย SELinux ซึ่ง
กำหนดโดเมนและป้ายกำกับของโดเมน คุณอาจต้องสร้างไฟล์นโยบายใหม่ใน
/device/manufacturer/device-name/sepolicy
แต่ควรพยายามอัปเดตไฟล์ที่มีอยู่หากเป็นไปได้
ไฟล์บริบท
ไฟล์บริบทคือที่ที่คุณระบุป้ายกำกับสำหรับออบเจ็กต์
- file_contextsจะกำหนดป้ายกำกับให้กับไฟล์และใช้โดยคอมโพเนนต์ต่างๆ ใน พื้นที่ผู้ใช้ เมื่อสร้างนโยบายใหม่ ให้สร้างหรืออัปเดตไฟล์นี้ เพื่อกำหนดป้ายกำกับใหม่ให้กับไฟล์ หากต้องการใช้- file_contextsใหม่ ให้สร้างอิมเมจระบบไฟล์ใหม่หรือเรียกใช้- restoreconในไฟล์ที่จะ ติดป้ายกำกับใหม่ เมื่ออัปเกรด ระบบจะนำการเปลี่ยนแปลงใน- file_contextsไปใช้กับพาร์ติชันระบบและพาร์ติชัน userdata โดยอัตโนมัติ ซึ่งเป็นส่วนหนึ่งของการอัปเกรด นอกจากนี้ คุณยังใช้การเปลี่ยนแปลงโดยอัตโนมัติเมื่ออัปเกรดเป็นพาร์ติชันอื่นๆ ได้ด้วย โดยเพิ่ม- restorecon_recursiveการเรียกใช้boardไฟล์ init.rc หลังจากที่เมานต์พาร์ติชันเป็นแบบอ่าน/เขียนแล้ว
- genfs_contextsกำหนดป้ายกำกับให้กับระบบไฟล์ เช่น- procหรือ- vfatที่ไม่รองรับแอตทริบิวต์ แบบขยาย การกำหนดค่านี้จะโหลดเป็นส่วนหนึ่งของนโยบายเคอร์เนล แต่การเปลี่ยนแปลงอาจไม่มีผลกับ Inode ในแกนกลาง ซึ่งต้องรีบูตหรือ ยกเลิกการเชื่อมต่อและเชื่อมต่อระบบไฟล์ใหม่เพื่อให้การเปลี่ยนแปลงมีผลอย่างเต็มที่ นอกจากนี้ คุณยังกำหนดป้ายกำกับที่เฉพาะเจาะจงให้กับเมานต์ที่เฉพาะเจาะจงได้ด้วย เช่น- vfatโดยใช้ตัวเลือก- context=mount
- property_contextsกำหนดป้ายกำกับให้กับพร็อพเพอร์ตี้ของระบบ Android เพื่อ ควบคุมว่ากระบวนการใดบ้างที่ตั้งค่าพร็อพเพอร์ตี้ได้- initจะอ่านการกำหนดค่านี้ในระหว่างการเริ่มต้น
- service_contextsกำหนดป้ายกำกับให้กับบริการ Binder ของ Android เพื่อ ควบคุมกระบวนการที่สามารถเพิ่ม (ลงทะเบียน) และค้นหา (ค้นหา) Binder อ้างอิงสำหรับบริการ- servicemanagerจะอ่านการกำหนดค่านี้ในระหว่างการเริ่มต้น
- seapp_contextsกำหนดป้ายกำกับให้กับกระบวนการของแอปและ- /data/dataไดเรกทอรี- zygoteจะอ่านการกำหนดค่านี้เมื่อเปิดแอปแต่ละครั้ง และ- installdจะอ่านการกำหนดค่านี้ในระหว่างการเริ่มต้น
- mac_permissions.xmlจะกำหนดแท็ก- seinfoให้กับแอป โดยอิงตามลายเซ็นและชื่อแพ็กเกจ (ไม่บังคับ) จากนั้นจะใช้แท็ก- seinfoเป็นคีย์ในไฟล์- seapp_contextsเพื่อกำหนดป้ายกำกับที่เฉพาะเจาะจงให้กับแอปทั้งหมดที่มีแท็ก- seinfoนั้น โดย- system_serverจะอ่านการกำหนดค่านี้ในระหว่างการเริ่มต้น
- keystore2_key_contextsมอบหมายป้ายกำกับให้กับเนมสเปซ Keystore 2- keystore2Daemon จะบังคับใช้เนมสเปซเหล่านี้ Keystore มีเนมสเปซที่อิงตาม UID/AID มาโดยตลอด นอกจากนี้ Keystore 2 ยังบังคับใช้ sepolicy ที่กำหนดเนมสเปซด้วย ดูคำอธิบายโดยละเอียดเกี่ยวกับรูปแบบและข้อกำหนดของไฟล์นี้ได้ที่นี่
ไฟล์ makefile ของ BoardConfig.mk
หลังจากแก้ไขหรือเพิ่มไฟล์นโยบายและบริบทแล้ว ให้อัปเดต
/device/manufacturer/device-name/BoardConfig.mk
makefile เพื่ออ้างอิงไดเรกทอรีย่อย 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 ตอนนี้คุณสามารถ ปรับแต่งนโยบาย SELinux ให้รองรับการเพิ่มของคุณเองใน ระบบปฏิบัติการ Android ตามที่อธิบายไว้ใน การปรับแต่ง หรือยืนยัน การตั้งค่าที่มีอยู่ตามที่กล่าวถึงใน การตรวจสอบ
เมื่อมีไฟล์นโยบายใหม่และการอัปเดต 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 ขึ้นไป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_*ดูรายละเอียดเกี่ยวกับการตั้งค่านี้ได้ใน README ในsystem/sepolicy
- ตรวจสอบไฟล์ init.device.rc และ fstab.device และ
      ตรวจสอบว่าทุกการใช้ mountสอดคล้องกับ ระบบไฟล์ที่มีป้ายกำกับอย่างถูกต้อง หรือมีการระบุตัวเลือกcontext= mount
- ตรวจสอบการปฏิเสธแต่ละรายการและสร้างนโยบาย SELinux เพื่อจัดการแต่ละรายการอย่างเหมาะสม ดู ตัวอย่างในการปรับแต่ง
คุณควรเริ่มต้นด้วยนโยบายใน AOSP แล้วจึงต่อยอดเพื่อ การปรับแต่งของคุณเอง ดูข้อมูลเพิ่มเติมเกี่ยวกับกลยุทธ์นโยบายและ ดูขั้นตอนเหล่านี้บางส่วนอย่างละเอียดได้ที่ การเขียนนโยบาย SELinux
กรณีการใช้งาน
ตัวอย่างการใช้ช่องโหว่ที่เฉพาะเจาะจงซึ่งควรพิจารณาเมื่อสร้างซอฟต์แวร์และนโยบาย SELinux ที่เกี่ยวข้องมีดังนี้
Symlink: เนื่องจาก Symlink ปรากฏเป็นไฟล์ จึงมัก
อ่านเป็นไฟล์ ซึ่งอาจนำไปสู่การใช้ช่องโหว่ ตัวอย่างเช่น คอมโพเนนต์ที่มีสิทธิ์บางอย่าง เช่น init จะเปลี่ยนสิทธิ์ของไฟล์บางไฟล์
บางครั้งก็เปิดมากเกินไป
จากนั้นผู้โจมตีอาจแทนที่ไฟล์เหล่านั้นด้วยลิงก์สัญลักษณ์ไปยังโค้ดที่ตนควบคุม ซึ่งจะทำให้ผู้โจมตีเขียนทับไฟล์ใดก็ได้ แต่หากคุณทราบว่าแอปของคุณไม่เคยข้ามลิงก์สัญลักษณ์ คุณก็สามารถห้ามไม่ให้แอปทำเช่นนั้นได้ด้วย SELinux
ไฟล์ระบบ: พิจารณาคลาสของไฟล์ระบบที่
ควรแก้ไขโดยเซิร์ฟเวอร์ระบบเท่านั้น อย่างไรก็ตาม เนื่องจาก netd,
init และ vold ทำงานในฐานะรูท จึงเข้าถึงไฟล์ระบบเหล่านั้นได้ ดังนั้นหาก netd ถูกบุกรุก ก็อาจทำให้ไฟล์เหล่านั้นและอาจรวมถึงเซิร์ฟเวอร์ของระบบเองถูกบุกรุกด้วย
SELinux ช่วยให้คุณระบุไฟล์เหล่านั้นเป็นไฟล์ข้อมูลเซิร์ฟเวอร์ของระบบได้
ดังนั้น โดเมนเดียวที่มีสิทธิ์อ่าน/เขียนไฟล์เหล่านี้คือเซิร์ฟเวอร์ระบบ
แม้ว่า netd จะถูกบุกรุก แต่ก็ไม่สามารถเปลี่ยนโดเมนเป็นโดเมนเซิร์ฟเวอร์ของระบบและเข้าถึงไฟล์ระบบเหล่านั้นได้ แม้ว่าจะทำงานในฐานะรูทก็ตาม
ข้อมูลแอป: อีกตัวอย่างหนึ่งคือคลาสของฟังก์ชันที่ ต้องเรียกใช้ในฐานะรูท แต่ไม่ควรได้รับสิทธิ์เข้าถึงข้อมูลแอป ซึ่งมีประโยชน์อย่างยิ่งเนื่องจากสามารถยืนยันได้ในหลายๆ ด้าน เช่น ห้ามไม่ให้โดเมนบางโดเมนที่ไม่เกี่ยวข้องกับข้อมูลแอปเข้าถึงอินเทอร์เน็ต
setattr: สำหรับคำสั่งต่างๆ เช่น chmod และ
chown คุณสามารถระบุชุดไฟล์ที่โดเมนที่เชื่อมโยงสามารถดำเนินการ setattr ได้ การดำเนินการใดๆ ที่อยู่นอกเหนือจากนี้อาจ
ถูกห้ามจากการเปลี่ยนแปลงเหล่านี้ แม้แต่โดยรูท ดังนั้น แอปอาจเรียกใช้
chmod และ chown กับรายการที่ติดป้ายกำกับว่า
app_data_files แต่ไม่ใช่ shell_data_files
หรือ system_data_files
