หน้านี้จะอธิบายวิธีสร้างนโยบาย 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
จึงต้องติดตั้งพาร์ติชันระบบและพาร์ติชันของผู้ให้บริการ
ก่อนหน้านี้เพื่อให้สามารถอ่านไฟล์ SELinux จากพาร์ติชันเหล่านั้นและผสานรวม
กับไฟล์ SELinux หลักในไดเรกทอรีระบบ (ก่อนที่จะโหลดลงใน
เคอร์เนล)
ไฟล์แหล่งข้อมูล
ตรรกะสำหรับการสร้าง SELinux อยู่ในไฟล์ต่อไปนี้
-
external/selinux
: โปรเจ็กต์ SELinux ภายนอก ใช้เพื่อ สร้างยูทิลิตีบรรทัดคำสั่ง HOST เพื่อคอมไพล์นโยบายและป้ายกำกับ SELinux-
external/selinux/libselinux
: Android ใช้เฉพาะชุดย่อย ของโปรเจ็กต์libselinux
ภายนอกร่วมกับการปรับแต่ง บางอย่างที่เฉพาะเจาะจงสำหรับ Android โปรดดูรายละเอียดที่external/selinux/README.android
-
external/selinux/libsepol
: -
external/selinux/checkpolicy
: คอมไพเลอร์นโยบาย SELinux (ไฟล์ที่เรียกใช้ในโฮสต์:checkpolicy
,checkmodule
, และdispol
) ขึ้นอยู่กับlibsepol
-
-
system/sepolicy
: การกำหนดค่าหลักของนโยบาย SELinux ของ Android รวมถึงบริบทและไฟล์นโยบาย ตรรกะการสร้าง sepolicy หลัก ก็อยู่ที่นี่ด้วย (system/sepolicy/Android.mk
)
ดูรายละเอียดเพิ่มเติมเกี่ยวกับไฟล์ใน system/sepolicy
การใช้งาน SELinux
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/sepolicy
BOARD_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_version
- sepolicy: เอาต์พุตไบนารีหลังจากรวมไฟล์นโยบาย
(เช่น
security_classes
,initial_sids
และ*.te
) file_contexts
property_contexts
seapp_contexts
service_contexts
system/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.mk
นโยบายนี้อยู่ในตำแหน่งต่อไปนี้
ตำแหน่ง | ประกอบด้วย |
---|---|
system/sepolicy/public |
API ของ sepolicy ของแพลตฟอร์ม |
system/sepolicy/private |
รายละเอียดการติดตั้งใช้งานแพลตฟอร์ม (ผู้ให้บริการไม่ต้องสนใจ) |
system/sepolicy/vendor |
ไฟล์นโยบายและบริบทที่ผู้ให้บริการใช้ได้ (ผู้ให้บริการจะละเว้นก็ได้หากต้องการ) |
BOARD_SEPOLICY_DIRS |
sepolicy ของผู้ให้บริการ |
BOARD_ODM_SEPOLICY_DIRS (Android 9 ขึ้นไป) |
Odm sepolicy |
SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS (Android 11 ขึ้นไป) |
API ของ sepolicy ของ System_ext |
SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS (Android 11 ขึ้นไป) |
รายละเอียดการใช้งาน System_ext (ผู้ให้บริการสามารถข้ามได้) |
PRODUCT_PUBLIC_SEPOLICY_DIRS (Android 11 ขึ้นไป) |
API sepolicy ของผลิตภัณฑ์ |
PRODUCT_PRIVATE_SEPOLICY_DIRS (Android 11 ขึ้นไป) |
รายละเอียดการใช้งานผลิตภัณฑ์ (ผู้ให้บริการไม่ต้องสนใจ) |
ระบบบิลด์จะใช้นโยบายนี้และสร้างคอมโพเนนต์นโยบายของระบบ, system_ext, ผลิตภัณฑ์, ผู้ให้บริการ และ odm ในพาร์ติชันที่เกี่ยวข้อง ขั้นตอนมีดังนี้
- การแปลงนโยบายเป็นรูปแบบ SELinux Common Intermediate Language (CIL)
โดยเฉพาะ
- นโยบายแพลตฟอร์มสาธารณะ (ระบบ + system_ext + ผลิตภัณฑ์)
- นโยบายส่วนตัวและนโยบายสาธารณะรวมกัน
- สาธารณะ + ผู้ขาย และ
BOARD_SEPOLICY_DIRS
นโยบาย
- การกำหนดเวอร์ชันของนโยบายที่เผยแพร่ต่อสาธารณะซึ่งเป็นส่วนหนึ่งของนโยบายผู้ให้บริการ
ดำเนินการโดยใช้นโยบาย CIL สาธารณะที่สร้างขึ้นเพื่อแจ้งนโยบายสาธารณะ + ผู้ให้บริการ +
BOARD_SEPOLICY_DIRS
ที่รวมกันว่าส่วนใดที่ต้องเปลี่ยนเป็นแอตทริบิวต์ที่จะลิงก์กับนโยบายแพลตฟอร์ม - สร้างไฟล์การแมปที่ลิงก์แพลตฟอร์มและชิ้นส่วนของผู้ให้บริการ ในขั้นต้น การดำเนินการนี้จะเพียงลิงก์ประเภทจากนโยบายสาธารณะกับ แอตทริบิวต์ที่เกี่ยวข้องในนโยบายของผู้ให้บริการ ต่อมาการดำเนินการนี้จะ เป็นพื้นฐานสำหรับไฟล์ที่ดูแลรักษาในแพลตฟอร์มเวอร์ชันในอนาคตด้วย ซึ่งจะช่วยให้ มีความเข้ากันได้กับการกำหนดเป้าหมายนโยบายของผู้ให้บริการในแพลตฟอร์มเวอร์ชันนี้
- การรวมไฟล์นโยบาย (อธิบายทั้งโซลูชันในอุปกรณ์และโซลูชันที่คอมไพล์ล่วงหน้า)
- รวมการแมป นโยบายแพลตฟอร์ม และนโยบายของผู้ให้บริการ
- คอมไพล์ไฟล์นโยบายไบนารีเอาต์พุต
นโยบายความปลอดภัยสาธารณะของแพลตฟอร์ม
นโยบายความปลอดภัยสาธารณะของแพลตฟอร์มประกอบด้วยทุกอย่างที่กำหนดไว้ใน
system/sepolicy/public
แพลตฟอร์มสามารถถือว่าประเภทและ
แอตทริบิวต์ที่กำหนดไว้ภายใต้นโยบายสาธารณะเป็น API ที่เสถียรสำหรับแพลตฟอร์มเวอร์ชันที่กำหนด
ซึ่งเป็นส่วนหนึ่งของ sepolicy ที่แพลตฟอร์มส่งออก
ซึ่งนักพัฒนาด้านนโยบายของผู้ให้บริการ (เช่น อุปกรณ์) อาจเขียนนโยบายเพิ่มเติม
ที่เฉพาะเจาะจงสำหรับอุปกรณ์
ประเภทจะมีการควบคุมเวอร์ชันตามเวอร์ชันของนโยบายที่เขียนไฟล์ของผู้ให้บริการ
โดยกำหนดโดยPLATFORM_SEPOLICY_VERSION
ตัวแปรบิลด์ จากนั้นจะรวมนโยบายสาธารณะที่กำหนดเวอร์ชันไว้กับ
นโยบายของผู้ให้บริการและ (ในรูปแบบเดิม) ในนโยบายแพลตฟอร์ม ดังนั้น
นโยบายสุดท้ายจึงรวมถึงนโยบายแพลตฟอร์มส่วนตัว นโยบายสาธารณะของ
sepolicy ของแพลตฟอร์มปัจจุบัน นโยบายเฉพาะของอุปกรณ์ และนโยบายสาธารณะที่มีการกำหนดเวอร์ชัน
ซึ่งสอดคล้องกับเวอร์ชันของแพลตฟอร์มที่ใช้อ้างอิงในการเขียนนโยบายของอุปกรณ์
sepolicy ส่วนตัวของแพลตฟอร์ม
นโยบายความปลอดภัยของแพลตฟอร์มส่วนตัวประกอบด้วยทุกอย่างที่กำหนดไว้ใน
/system/sepolicy/private
ส่วนนี้ของนโยบายจะกำหนดประเภท สิทธิ์ และแอตทริบิวต์ที่จำเป็นสำหรับฟังก์ชันการทำงานของแพลตฟอร์ม
ระบบจะไม่ส่งออกข้อมูลเหล่านี้ไปยังผู้เขียนนโยบายของ vendor/device
ผู้เขียนนโยบายที่ไม่ใช่แพลตฟอร์มต้องไม่เขียนส่วนขยายนโยบาย
โดยอิงตามประเภท/แอตทริบิวต์/กฎที่กำหนดไว้ใน sepolicy ส่วนตัวของแพลตฟอร์ม นอกจากนี้
กฎเหล่านี้ยังสามารถแก้ไขได้หรืออาจหายไปเมื่อมีการอัปเดต
เฉพาะเฟรมเวิร์ก
การแมปส่วนตัวของแพลตฟอร์ม
การแมปส่วนตัวของแพลตฟอร์มประกอบด้วยข้อความนโยบายที่แมปแอตทริบิวต์
ที่เปิดเผยในนโยบายสาธารณะของแพลตฟอร์มในแพลตฟอร์มเวอร์ชันก่อนหน้ากับ
ประเภทที่เฉพาะเจาะจงซึ่งใช้ใน sepolicy สาธารณะของแพลตฟอร์มปัจจุบัน เพื่อให้มั่นใจว่านโยบายของผู้ให้บริการที่เขียนขึ้นโดยอิงตามแอตทริบิวต์สาธารณะของแพลตฟอร์มจากเวอร์ชัน sepolicy สาธารณะของแพลตฟอร์มก่อนหน้าจะยังคงใช้งานได้
การกำหนดเวอร์ชันจะอิงตามPLATFORM_SEPOLICY_VERSION
ตัวแปรบิลด์
ที่ตั้งค่าไว้ใน AOSP สำหรับเวอร์ชันแพลตฟอร์มที่กำหนด มีไฟล์การแมปแยกต่างหากสำหรับ
แพลตฟอร์มเวอร์ชันก่อนหน้าแต่ละเวอร์ชันซึ่งคาดว่าแพลตฟอร์มนี้จะยอมรับ
นโยบายของผู้ให้บริการ โปรดดูรายละเอียดเพิ่มเติมที่หัวข้อความเข้ากันได้
Android 11 ขึ้นไป
system_ext และ sepolicy ของผลิตภัณฑ์
ใน Android 11 มีการเพิ่มนโยบาย system_ext และนโยบายผลิตภัณฑ์ เช่นเดียวกับนโยบายแพลตฟอร์ม นโยบาย system_ext และนโยบายผลิตภัณฑ์จะแยกออกเป็นนโยบายสาธารณะและ นโยบายส่วนตัว
ระบบจะส่งออกนโยบายสาธารณะไปยังผู้ให้บริการ ประเภทและแอตทริบิวต์จะกลายเป็น API ที่เสถียร และ
นโยบายของผู้ให้บริการสามารถอ้างอิงประเภทและแอตทริบิวต์ในนโยบายสาธารณะได้ ประเภทจะ
มีการกำหนดเวอร์ชันตาม PLATFORM_SEPOLICY_VERSION
และนโยบาย
ที่มีการกำหนดเวอร์ชันจะรวมอยู่ในนโยบายของผู้ให้บริการ นโยบายเดิมจะรวมอยู่ในแต่ละ
พาร์ติชัน system_ext และ product
นโยบายส่วนตัวมีประเภท สิทธิ์ และ แอตทริบิวต์ที่จำเป็นสำหรับฟังก์ชันการทำงานของพาร์ติชัน system_ext และพาร์ติชันผลิตภัณฑ์ นโยบายส่วนตัวจะไม่แสดงต่อผู้ให้บริการ ซึ่งหมายความว่ากฎเหล่านี้เป็นกฎภายใน และสามารถแก้ไขได้
การแมป system_ext และผลิตภัณฑ์
system_ext และ product ได้รับอนุญาตให้ส่งออกประเภทสาธารณะที่กำหนดไปยัง vendor อย่างไรก็ตาม พาร์ทเนอร์แต่ละรายมีหน้าที่รับผิดชอบในการรักษาความเข้ากันได้ พาร์ทเนอร์สามารถระบุไฟล์การแมปของตนเองเพื่อแมปแอตทริบิวต์ที่มีการกำหนดเวอร์ชันของเวอร์ชันก่อนหน้ากับประเภทที่เฉพาะเจาะจงซึ่งใช้ใน sepolicy สาธารณะปัจจุบันเพื่อความเข้ากันได้
- หากต้องการติดตั้งไฟล์การแมปสำหรับ system_ext ให้วางไฟล์ cil ที่มี
ข้อมูลการแมปที่ต้องการไว้ใน
{SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil
จากนั้นเพิ่มsystem_ext_{ver}.cil
ลงในPRODUCT_PACKAGES
- หากต้องการติดตั้งไฟล์การแมปสำหรับผลิตภัณฑ์ ให้วางไฟล์ CIL ที่มี
ข้อมูลการแมปที่ต้องการไว้ใน
{PRODUCT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil
จากนั้นเพิ่มproduct_{ver}.cil
ไปยังPRODUCT_PACKAGES
ดูตัวอย่าง ซึ่งเพิ่มไฟล์การแมปพาร์ติชันผลิตภัณฑ์ของอุปกรณ์ 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