หน้านี้จะอธิบายวิธีสร้างนโยบาย SELinux นโยบาย SELinux สร้างขึ้นจากการรวมกันของนโยบาย AOSP หลัก (แพลตฟอร์ม) และนโยบายเฉพาะอุปกรณ์ (ผู้ให้บริการ) ขั้นตอนการสร้างนโยบาย SELinux สำหรับ Android 4.4 ถึง Android
7.0 จะรวมชิ้นส่วน sepolicy ทั้งหมด แล้วสร้างไฟล์แบบ Monolithic ในไดเรกทอรีราก
ซึ่งหมายความว่าผู้ให้บริการ SoC และผู้ผลิต ODM ต้องแก้ไข
boot.img
(สำหรับอุปกรณ์ที่ไม่ใช่ A/B) หรือ system.img (สำหรับอุปกรณ์ A/B) ทุกครั้งที่มีการแก้ไขนโยบาย
ใน Android 8.0 ขึ้นไป นโยบายแพลตฟอร์มและนโยบายของผู้ให้บริการจะสร้างแยกกัน
SoC และ OEM สามารถอัปเดตส่วนของนโยบาย สร้างอิมเมจ
(เช่น vendor.img และ boot.img)
จากนั้นอัปเดตอิมเมจเหล่านั้นโดยไม่ขึ้นอยู่กับการอัปเดตแพลตฟอร์ม
อย่างไรก็ตาม เนื่องจากไฟล์นโยบาย SELinux แบบแยกส่วนจะจัดเก็บไว้ในพาร์ติชัน /vendor
กระบวนการ init จึงต้องติดตั้งพาร์ติชัน system และ vendor
ก่อนหน้านี้เพื่อให้สามารถอ่านไฟล์ SELinux จากพาร์ติชันเหล่านั้นและผสานรวม
กับไฟล์ SELinux หลักในไดเรกทอรี system (ก่อนที่จะโหลดลงใน
เคอร์เนล)
ไฟล์แหล่งข้อมูล
ตรรกะสำหรับการสร้าง SELinux อยู่ในไฟล์ต่อไปนี้
-
external/selinux: โปรเจ็กต์ SELinux ภายนอก ใช้เพื่อ สร้างยูทิลิตีบรรทัดคำสั่ง HOST เพื่อคอมไพล์นโยบายและป้ายกำกับ SELinux-
external/selinux/libselinux: Android ใช้เฉพาะชุดย่อย ของโปรเจ็กต์libselinuxภายนอกร่วมกับการปรับแต่งบางอย่าง ที่เฉพาะเจาะจงสำหรับ Android โปรดดูรายละเอียดที่external/selinux/README.android -
external/selinux/libsepol: -
external/selinux/checkpolicy: SELinux policy compiler (host executables:checkpolicy,checkmodule, anddispol). Depends onlibsepol.
-
-
system/sepolicy: การกำหนดค่าหลักของนโยบาย SELinux ของ Android รวมถึงบริบทและไฟล์นโยบาย ตรรกะการสร้าง sepolicy หลัก ก็อยู่ที่นี่ด้วย (system/sepolicy/Android.mk)
ดูรายละเอียดเพิ่มเติมเกี่ยวกับไฟล์ใน system/sepolicy ได้ที่
ไฟล์คีย์
Android 7.x และต่ำกว่า
ส่วนนี้จะครอบคลุมวิธีสร้างนโยบาย SELinux ใน Android 7.x และต่ำกว่า
กระบวนการสร้างสำหรับ Android 7.x และต่ำกว่า
นโยบาย SELinux สร้างขึ้นโดยการรวมนโยบายหลักของ AOSP เข้ากับการปรับแต่งเฉพาะอุปกรณ์
จากนั้นระบบจะส่งนโยบายที่รวมกันไปยังคอมไพเลอร์นโยบายและ
เครื่องมือตรวจสอบต่างๆ การปรับแต่งเฉพาะอุปกรณ์จะทำผ่านตัวแปร
BOARD_SEPOLICY_DIRS ที่กำหนดไว้ในไฟล์
Boardconfig.mk เฉพาะอุปกรณ์ ตัวแปรการสร้างส่วนกลางนี้มีรายการไดเรกทอรีที่ระบุลำดับการค้นหาไฟล์นโยบายเพิ่มเติม
ตัวอย่างเช่น ผู้จำหน่าย SoC และ ODM อาจเพิ่มไดเรกทอรีของตนเอง โดยไดเรกทอรีหนึ่งสำหรับการตั้งค่าเฉพาะ SoC และอีกไดเรกทอรีหนึ่งสำหรับการตั้งค่าเฉพาะอุปกรณ์ เพื่อสร้าง การกำหนดค่า SELinux สุดท้ายสำหรับอุปกรณ์ที่กำหนด
BOARD_SEPOLICY_DIRS += device/SoC/common/sepolicyBOARD_SEPOLICY_DIRS += device/SoC/DEVICE/sepolicy
ระบบจะต่อเนื้อหาของไฟล์ file_contexts ใน system/sepolicy และ
BOARD_SEPOLICY_DIRS เพื่อสร้าง
file_contexts.bin ในอุปกรณ์

รูปที่ 1 ตรรกะการสร้าง SELinux
ไฟล์ sepolicy ประกอบด้วยไฟล์ต้นฉบับหลายไฟล์ ดังนี้
- ข้อความธรรมดา
policy.confสร้างขึ้นโดยการต่อกันของsecurity_classes,initial_sids, ไฟล์*.te,genfs_contextsและport_contextsตามลำดับ - สำหรับแต่ละไฟล์ (เช่น
security_classes) เนื้อหาของไฟล์คือ การต่อกันของไฟล์ที่มีชื่อเดียวกันภายใต้system/sepolicy/และBOARDS_SEPOLICY_DIRS - ระบบจะส่ง
policy.confไปยังคอมไพเลอร์ SELinux เพื่อตรวจสอบไวยากรณ์ และคอมไพล์เป็นรูปแบบไบนารีเป็นsepolicyในอุปกรณ์
รูปที่ 2 ไฟล์นโยบาย SELinux
ไฟล์ SELinux
หลังจากคอมไพล์แล้ว อุปกรณ์ Android ที่ใช้เวอร์ชัน 7.x และเวอร์ชันก่อนหน้ามักจะมีไฟล์ที่เกี่ยวข้องกับ SELinux ดังนี้
selinux_versionsepolicy: เอาต์พุตไบนารีหลังจากรวมไฟล์นโยบาย (เช่นsecurity_classes,initial_sidsและ*.te)file_contextsproperty_contextsseapp_contextsservice_contextssystem/etc/mac_permissions.xml
ดูรายละเอียดเพิ่มเติมได้ที่ติดตั้งใช้งาน SELinux
การเริ่มต้น SELinux
เมื่อระบบบูตขึ้นมา SELinux จะอยู่ในโหมดที่อนุญาต (และไม่ได้อยู่ในโหมดบังคับ) กระบวนการ init จะดำเนินการต่อไปนี้
- โหลดไฟล์
sepolicyจาก Ramdisk ลงในเคอร์เนลผ่าน/sys/fs/selinux/load - เปลี่ยน SELinux เป็นโหมดบังคับ
- เรียกใช้
re-exec()เพื่อใช้กฎโดเมน SELinux กับตัวมันเอง
หากต้องการลดเวลาในการบูต ให้re-exec()ในinitโดยเร็วที่สุด
Android 8.0 ขึ้นไป
ใน Android 8.0 นโยบาย SELinux จะแยกออกเป็นคอมโพเนนต์แพลตฟอร์มและคอมโพเนนต์ของผู้ให้บริการ เพื่อให้สามารถอัปเดตนโยบายแพลตฟอร์มและนโยบายของผู้ให้บริการได้อย่างอิสระ พร้อมทั้งรักษาความเข้ากันได้
นอกจากนี้ sepolicy ของแพลตฟอร์มยังแยกออกเป็นส่วนแพลตฟอร์มส่วนตัวและแพลตฟอร์มสาธารณะ เพื่อส่งออกประเภทและแอตทริบิวต์ที่เฉพาะเจาะจงไปยังผู้เขียนนโยบายของผู้ให้บริการ เรารับประกันว่าจะรักษาประเภท/แอตทริบิวต์สาธารณะของแพลตฟอร์มให้เป็น API ที่เสถียรสำหรับแพลตฟอร์มเวอร์ชันที่กำหนด การรับประกันความเข้ากันได้กับประเภท/แอตทริบิวต์สาธารณะของแพลตฟอร์มเวอร์ชันก่อนหน้า สามารถทำได้หลายเวอร์ชันโดยใช้ไฟล์การแมปแพลตฟอร์ม
กระบวนการบิลด์สำหรับ Android 8.0
นโยบาย SELinux ใน Android 8.0 สร้างขึ้นโดยการรวมชิ้นส่วนจาก
/system และ /vendor ตรรกะในการตั้งค่านี้อย่างเหมาะสมอยู่ใน
/platform/system/sepolicy/Android.bp
นโยบายนี้อยู่ในตำแหน่งต่อไปนี้
| ตำแหน่ง | ประกอบด้วย |
|---|---|
system/sepolicy/public |
Platform sepolicy API |
system/sepolicy/private |
รายละเอียดการติดตั้งใช้งานแพลตฟอร์ม (ผู้ให้บริการไม่ต้องสนใจ) |
system/sepolicy/vendor |
ไฟล์นโยบายและบริบทที่ผู้ให้บริการใช้ได้ (ผู้ให้บริการจะละเว้นก็ได้) |
BOARD_SEPOLICY_DIRS |
sepolicy ของผู้ให้บริการ |
BOARD_ODM_SEPOLICY_DIRS (Android 9 ขึ้นไป) |
sepolicy ของ ODM |
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 ขึ้นไป) |
Product sepolicy API |
PRODUCT_PRIVATE_SEPOLICY_DIRS (Android 11 ขึ้นไป) |
รายละเอียดการติดตั้งใช้งานผลิตภัณฑ์ (ผู้ให้บริการไม่ต้องสนใจ) |
ระบบบิลด์จะใช้นโยบายนี้และสร้างคอมโพเนนต์นโยบาย system, system_ext, product, vendor และ odm ในพาร์ติชันที่เกี่ยวข้อง ขั้นตอนมีดังนี้
- แปลงนโยบายเป็นรูปแบบ SELinux Common Intermediate Language (CIL)
โดยเฉพาะ
- นโยบายแพลตฟอร์มสาธารณะ (
system,system_ext,product) - นโยบายส่วนตัวและสาธารณะร่วมกัน
- สาธารณะ ผู้ให้บริการ และ
BOARD_SEPOLICY_DIRSนโยบาย
- นโยบายแพลตฟอร์มสาธารณะ (
- จัดเวอร์ชันนโยบายที่สาธารณะระบุไว้เป็นส่วนหนึ่งของนโยบายของผู้ให้บริการ
ใช้นโยบาย CIL สาธารณะที่สร้างขึ้นเพื่อแจ้งนโยบายสาธารณะและ
นโยบายของผู้ให้บริการและ
BOARD_SEPOLICY_DIRSรวมกันว่าส่วนใดที่ต้อง เปลี่ยนเป็นแอตทริบิวต์ที่ลิงก์กับนโยบายของแพลตฟอร์ม - สร้างไฟล์การแมปที่ลิงก์แพลตฟอร์มและชิ้นส่วนของผู้ให้บริการ ในขั้นต้น การดำเนินการนี้จะลิงก์ประเภทจากนโยบายสาธารณะกับ แอตทริบิวต์ที่เกี่ยวข้องในนโยบายของผู้ให้บริการ ต่อมายังเป็น พื้นฐานสำหรับไฟล์ที่ดูแลรักษาในแพลตฟอร์มเวอร์ชันในอนาคต ซึ่งช่วยให้ เข้ากันได้กับการกำหนดเป้าหมายนโยบายของผู้ให้บริการในแพลตฟอร์มเวอร์ชันนี้
- รวมไฟล์นโยบาย (อธิบายทั้งโซลูชันในอุปกรณ์และโซลูชันที่คอมไพล์ล่วงหน้า)
- รวมการแมป แพลตฟอร์ม และนโยบายของผู้ให้บริการ
- คอมไพล์ไฟล์นโยบายไบนารีเอาต์พุต
นโยบายความปลอดภัยสาธารณะของแพลตฟอร์ม
sepolicy สาธารณะของแพลตฟอร์มมีทุกอย่างที่กำหนดไว้ใน
system/sepolicy/public แพลตฟอร์มสามารถถือว่าประเภทและ
แอตทริบิวต์ที่กำหนดไว้ภายใต้นโยบายสาธารณะเป็น API ที่เสถียรสำหรับแพลตฟอร์มเวอร์ชันที่กำหนด
ซึ่งเป็นส่วนหนึ่งของ sepolicy ที่แพลตฟอร์มส่งออก
ซึ่งนักพัฒนาด้านนโยบายของผู้ให้บริการ (นั่นคือ อุปกรณ์) สามารถเขียนนโยบายเพิ่มเติม
ที่เฉพาะเจาะจงสำหรับอุปกรณ์ได้
ประเภทจะมีการควบคุมเวอร์ชันตามเวอร์ชันของนโยบายที่เขียนไฟล์
ของผู้ให้บริการ โดยกำหนดโดยPLATFORM_SEPOLICY_VERSION
ตัวแปรบิลด์ จากนั้นจะรวมนโยบายสาธารณะที่กำหนดเวอร์ชันไว้กับ
นโยบายของผู้ให้บริการและ (ในรูปแบบเดิม) ในนโยบายแพลตฟอร์ม ดังนั้น
นโยบายสุดท้ายจึงรวมถึงนโยบายแพลตฟอร์มส่วนตัว นโยบายสาธารณะของ
sepolicy ของแพลตฟอร์มปัจจุบัน นโยบายเฉพาะของอุปกรณ์ และนโยบายสาธารณะที่มีการกำหนดเวอร์ชัน
ซึ่งสอดคล้องกับเวอร์ชันของแพลตฟอร์มที่ใช้อ้างอิงในการเขียนนโยบายของอุปกรณ์
sepolicy ส่วนตัวของแพลตฟอร์ม
นโยบายความปลอดภัยของแพลตฟอร์มส่วนตัวประกอบด้วยทุกอย่างที่กำหนดไว้ใน
/system/sepolicy/private ส่วนนี้ของนโยบายจะกำหนดประเภท สิทธิ์ และแอตทริบิวต์เฉพาะแพลตฟอร์มที่จำเป็นสำหรับฟังก์ชันการทำงานของแพลตฟอร์ม ระบบจะไม่ส่งออกข้อมูลเหล่านี้ไปยังผู้ให้บริการและผู้เขียนนโยบายอุปกรณ์
ผู้เขียนนโยบายที่ไม่ใช่แพลตฟอร์มต้องไม่เขียนส่วนขยายนโยบาย
ตามประเภท แอตทริบิวต์ และกฎที่กำหนดไว้ใน sepolicy ส่วนตัวของแพลตฟอร์ม นอกจากนี้
คุณยังแก้ไขกฎเหล่านี้ได้ หรือกฎอาจหายไปเมื่ออัปเดตเฉพาะเฟรมเวิร์ก
การแมปส่วนตัวของแพลตฟอร์ม
การแมปส่วนตัวของแพลตฟอร์มประกอบด้วยข้อความนโยบายที่แมปแอตทริบิวต์
ที่เปิดเผยในนโยบายสาธารณะของแพลตฟอร์มในแพลตฟอร์มเวอร์ชันก่อนหน้ากับ
ประเภทที่เฉพาะเจาะจงซึ่งใช้ใน sepolicy สาธารณะของแพลตฟอร์มปัจจุบัน เพื่อให้มั่นใจว่านโยบายของผู้ให้บริการที่เขียนขึ้นโดยอิงตามแอตทริบิวต์สาธารณะของแพลตฟอร์มจาก sepolicy สาธารณะของแพลตฟอร์มเวอร์ชันก่อนหน้าจะยังคงใช้งานได้
การกำหนดเวอร์ชันจะอิงตามPLATFORM_SEPOLICY_VERSIONตัวแปรบิลด์
ที่ตั้งค่าไว้ใน AOSP สำหรับเวอร์ชันแพลตฟอร์มที่กำหนด มีไฟล์การแมปแยกต่างหากสำหรับ
แพลตฟอร์มเวอร์ชันก่อนหน้าแต่ละเวอร์ชันซึ่งคาดว่าแพลตฟอร์มนี้จะยอมรับ
นโยบายของผู้ให้บริการ ดูรายละเอียดเพิ่มเติมได้ที่ความเข้ากันได้ของนโยบาย
Android 11 ขึ้นไป
ส่วนนี้จะอธิบายวิธีสร้างนโยบาย SELinux ใน Android 11 ขึ้นไป
system_ext และ sepolicy ของผลิตภัณฑ์
ใน Android 11 มีการเพิ่มนโยบาย system_ext และนโยบาย product เช่นเดียวกับนโยบาย sepolicy ของแพลตฟอร์ม system_extนโยบายproductและนโยบายproductจะแบ่งออกเป็น
นโยบายสาธารณะและนโยบายส่วนตัว
ระบบจะส่งออกนโยบายสาธารณะไปยังผู้ให้บริการ ประเภทและแอตทริบิวต์จะกลายเป็น API ที่เสถียร และ
นโยบายของผู้ให้บริการสามารถอ้างอิงประเภทและแอตทริบิวต์ในนโยบายสาธารณะได้ ประเภทต่างๆ จะ
มีการกำหนดเวอร์ชันตาม PLATFORM_SEPOLICY_VERSION และนโยบาย
ที่มีการกำหนดเวอร์ชันจะรวมอยู่ในนโยบายของผู้ให้บริการ นโยบายเดิมจะรวมอยู่ในพาร์ติชัน system_ext และ product แต่ละรายการ
นโยบายส่วนตัวมีประเภท สิทธิ์ และ
แอตทริบิวต์ที่จำเป็นสำหรับฟังก์ชันการแบ่งพาร์ติชัน system_ext และ product เท่านั้นsystem_extproduct
นโยบายส่วนตัวจะไม่แสดงต่อผู้ให้บริการ ซึ่งหมายความว่ากฎเหล่านี้เป็นกฎภายใน
และสามารถแก้ไขได้
การแมป system_ext และผลิตภัณฑ์
system_ext และ product ได้รับอนุญาตให้ส่งออกประเภทสาธารณะที่กำหนดไปยัง
ผู้ให้บริการ อย่างไรก็ตาม พาร์ทเนอร์แต่ละรายมีหน้าที่รับผิดชอบในการรักษา
ความเข้ากันได้ พาร์ทเนอร์สามารถระบุไฟล์การแมปของตนเองเพื่อแมปแอตทริบิวต์ที่มีการกำหนดเวอร์ชันของเวอร์ชันก่อนหน้ากับประเภทที่เฉพาะเจาะจงที่ใช้ใน sepolicy สาธารณะปัจจุบันเพื่อความเข้ากันได้
- หากต้องการติดตั้งไฟล์การจับคู่สำหรับ
system_extให้วางไฟล์ CIL ที่มี ข้อมูลการจับคู่ที่ต้องการไว้ใน{SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cilจากนั้นเพิ่มsystem_ext_{ver}.cilลงในPRODUCT_PACKAGES - หากต้องการติดตั้งไฟล์การจับคู่สำหรับ
productให้วางไฟล์ CIL ที่มี ข้อมูลการจับคู่ที่ต้องการไว้ใน{PRODUCT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cilจากนั้นเพิ่มproduct_{ver}.cilลงในPRODUCT_PACKAGES
ดูตัวอย่าง
ที่เพิ่มไฟล์การแมปของพาร์ติชัน product ของอุปกรณ์ Redbull
นโยบาย SELinux ที่คอมไพล์ล่วงหน้า
ก่อนที่ init จะเปิด SELinux init จะรวบรวมไฟล์ CIL ทั้งหมดจากพาร์ติชัน
(system, system_ext, product, vendor และ
odm) แล้วคอมไพล์เป็นนโยบายไบนารี ซึ่งเป็นรูปแบบที่โหลดไปยังเคอร์เนลได้ เนื่องจากการคอมไพล์ต้องใช้เวลา (โดยปกติคือ 1-2 วินาที) ระบบจึงคอมไพล์ไฟล์ CIL ล่วงหน้าในเวลาบิลด์และวางไว้ที่ /vendor/etc/selinux/precompiled_sepolicy หรือ /odm/etc/selinux/precompiled_sepolicy พร้อมกับแฮช sha256 ของไฟล์ CIL อินพุต ในขณะรันไทม์ 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