หน้านี้จะอธิบายวิธีสร้างนโยบาย SELinux นโยบาย SELinux สร้างขึ้นจากนโยบายหลักของ AOSP (แพลตฟอร์ม) และนโยบายเฉพาะอุปกรณ์ (ผู้ให้บริการ) ขั้นตอนการบิลด์นโยบาย SELinux สำหรับ Android 4.4 ถึง Android 7.0 จะผสานกลุ่ม sepolicy ทั้งหมด แล้วสร้างไฟล์แบบโมโนลิธิคในไดเรกทอรีรูท ซึ่งหมายความว่าผู้ให้บริการ 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 ซึ่งรวมถึงบริบทและไฟล์นโยบาย ตรรกะการสร้างนโยบายความปลอดภัยที่สำคัญก็อยู่ที่นี่ด้วย (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
จากแรมดิสก์ลงในเคอร์เนลผ่าน/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 |
sepolicy API ของแพลตฟอร์ม |
system/sepolicy/private |
รายละเอียดการติดตั้งใช้งานแพลตฟอร์ม (ผู้ให้บริการสามารถละเว้นได้) |
system/sepolicy/vendor |
ไฟล์นโยบายและบริบทที่ผู้ให้บริการใช้ได้ (ผู้ให้บริการสามารถละเว้นได้หากต้องการ) |
BOARD_SEPOLICY_DIRS |
นโยบายความปลอดภัยของผู้ให้บริการ |
BOARD_ODM_SEPOLICY_DIRS (Android 9 ขึ้นไป) |
Odm sepolicy |
SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS (Android 11 ขึ้นไป) |
sepolicy API ของ System_ext |
SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS (Android 11 ขึ้นไป) |
รายละเอียดการใช้งาน System_ext (ผู้ให้บริการสามารถละเว้นได้) |
PRODUCT_PUBLIC_SEPOLICY_DIRS (Android 11 ขึ้นไป) |
sepolicy API ของผลิตภัณฑ์ |
PRODUCT_PRIVATE_SEPOLICY_DIRS (Android 11 ขึ้นไป) |
รายละเอียดการติดตั้งใช้งานผลิตภัณฑ์ (ผู้ให้บริการสามารถละเว้นได้) |
ระบบบิลด์จะใช้นโยบายนี้เพื่อสร้างคอมโพเนนต์นโยบาย system, system_ext, product, vendor และ odm ในพาร์ติชันที่เกี่ยวข้อง ขั้นตอนต่างๆ มีดังนี้
- การเปลี่ยนนโยบายเป็นรูปแบบ Common Intermediate Language (CIL) ของ SELinux โดยเฉพาะอย่างยิ่งในกรณีต่อไปนี้
- นโยบายแพลตฟอร์มสาธารณะ (system + system_ext + product)
- นโยบายสาธารณะและนโยบายส่วนตัวรวมกัน
- นโยบายสาธารณะ + ผู้ให้บริการและ
BOARD_SEPOLICY_DIRS
- การกำหนดเวอร์ชันนโยบายที่เผยแพร่ต่อสาธารณะซึ่งเป็นส่วนหนึ่งของนโยบายของผู้ให้บริการ
ดำเนินการโดยใช้นโยบาย CIL สาธารณะที่ผลิตเพื่อแจ้งนโยบายแบบรวมสาธารณะ + ผู้ให้บริการ +
BOARD_SEPOLICY_DIRS
ว่าต้องเปลี่ยนส่วนใดให้กลายเป็นแอตทริบิวต์ที่จะลิงก์กับนโยบายแพลตฟอร์ม - การสร้างไฟล์การแมปที่ลิงก์ส่วนแพลตฟอร์มและส่วนผู้ให้บริการ ในช่วงแรก การดำเนินการนี้จะลิงก์ประเภทจากนโยบายสาธารณะกับแอตทริบิวต์ที่เกี่ยวข้องในนโยบายของผู้ให้บริการ หลังจากนั้นจะใช้เป็นพื้นฐานสำหรับไฟล์ที่ดูแลรักษาในแพลตฟอร์มเวอร์ชันในอนาคตด้วย ซึ่งจะช่วยให้ใช้งานร่วมกับนโยบายของผู้ให้บริการที่กำหนดเป้าหมายเป็นแพลตฟอร์มเวอร์ชันนี้ได้
- การรวมไฟล์นโยบาย (อธิบายทั้งโซลูชันในอุปกรณ์และโซลูชันที่คอมไพล์ไว้ล่วงหน้า)
- รวมการแมป นโยบายแพลตฟอร์ม และนโยบายของผู้ให้บริการ
- คอมไพล์ไฟล์นโยบายไบนารีเอาต์พุต
นโยบายความปลอดภัยสาธารณะของแพลตฟอร์ม
นโยบายความปลอดภัยสาธารณะของแพลตฟอร์มจะรวมทุกอย่างที่กําหนดไว้ในส่วน
system/sepolicy/public
แพลตฟอร์มจะถือว่าประเภทและแอตทริบิวต์ที่กําหนดไว้ในนโยบายสาธารณะเป็น API ที่เสถียรสําหรับแพลตฟอร์มเวอร์ชันหนึ่งๆ ข้อมูลนี้เป็นส่วนหนึ่งของ sepolicy ที่แพลตฟอร์มส่งออก ซึ่งนักพัฒนานโยบายของเวนเดอร์ (นั่นคือ อุปกรณ์) อาจเขียนนโยบายเฉพาะอุปกรณ์เพิ่มเติมได้
ประเภทจะมีเวอร์ชันตามเวอร์ชันของนโยบายที่ใช้เขียนไฟล์ของผู้ให้บริการ ซึ่งกำหนดโดยPLATFORM_SEPOLICY_VERSION
ตัวแปรบิลด์ จากนั้นนโยบายสาธารณะเวอร์ชันดังกล่าวจะรวมอยู่ในนโยบายของผู้ให้บริการและ (ในรูปแบบต้นฉบับ) ในนโยบายแพลตฟอร์ม ดังนั้น นโยบายสุดท้ายจึงประกอบด้วยนโยบายแพลตฟอร์มส่วนตัว นโยบายความปลอดภัยสาธารณะของแพลตฟอร์มปัจจุบัน นโยบายเฉพาะอุปกรณ์ และนโยบายสาธารณะเวอร์ชันที่สอดคล้องกับเวอร์ชันแพลตฟอร์มที่เขียนนโยบายอุปกรณ์
นโยบายความปลอดภัยส่วนตัวของแพลตฟอร์ม
นโยบายความปลอดภัยส่วนบุคคลของแพลตฟอร์มจะรวมทุกอย่างที่ระบุไว้ในส่วน
/system/sepolicy/private
ส่วนนี้ของนโยบายจะกำหนดประเภท สิทธิ์ และแอตทริบิวต์สำหรับแพลตฟอร์มเท่านั้นที่จําเป็นสําหรับฟังก์ชันการทํางานของแพลตฟอร์ม ระบบจะไม่ส่งออกข้อมูลเหล่านี้ไปยังผู้เขียนvendor/device
นโยบาย
ผู้เขียนนโยบายที่ไม่ใช่แพลตฟอร์มต้องไม่เขียนส่วนขยายนโยบายโดยอิงตามประเภท/แอตทริบิวต์/กฎที่กําหนดไว้ใน sepolicy ส่วนตัวของแพลตฟอร์ม นอกจากนี้ เรายังอนุญาตให้แก้ไขกฎเหล่านี้หรือกฎเหล่านี้อาจหายไปจากการอัปเดตเฟรมเวิร์กเท่านั้น
การแมปแบบส่วนตัวของแพลตฟอร์ม
การแมปแบบส่วนตัวของแพลตฟอร์มประกอบด้วยข้อความนโยบายที่แมปแอตทริบิวต์ที่แสดงในนโยบายสาธารณะของแพลตฟอร์มในเวอร์ชันก่อนหน้าของแพลตฟอร์มกับประเภทที่เฉพาะเจาะจงซึ่งใช้ในนโยบายความปลอดภัยสาธารณะของแพลตฟอร์มปัจจุบัน วิธีนี้ช่วยให้มั่นใจว่านโยบายของผู้ให้บริการที่เขียนขึ้นตามแอตทริบิวต์สาธารณะของแพลตฟอร์มจากเวอร์ชันนโยบายการรักษาความปลอดภัยสาธารณะของแพลตฟอร์มก่อนหน้าจะยังคงใช้งานได้ต่อไป การกำหนดเวอร์ชันจะอิงตามPLATFORM_SEPOLICY_VERSION
ตัวแปรบิลด์
ที่ตั้งค่าไว้ใน AOSP สำหรับเวอร์ชันแพลตฟอร์มหนึ่งๆ มีไฟล์การแมปแยกต่างหากสำหรับแพลตฟอร์มเวอร์ชันก่อนหน้าแต่ละเวอร์ชันที่คาดว่าแพลตฟอร์มนี้จะยอมรับนโยบายของผู้ให้บริการ โปรดดูรายละเอียดเพิ่มเติมที่หัวข้อความเข้ากันได้
Android 11 ขึ้นไป
system_ext และ product sepolicy
ใน Android 11 ระบบจะเพิ่มนโยบาย system_ext และนโยบายผลิตภัณฑ์ เช่นเดียวกับ platform sepolicy นโยบาย system_ext และนโยบายผลิตภัณฑ์จะแบ่งออกเป็นนโยบายสาธารณะและนโยบายส่วนตัว
ระบบจะส่งออกนโยบายสาธารณะไปยังผู้ให้บริการ ประเภทและแอตทริบิวต์จะกลายเป็น API ที่เสถียร และนโยบายของผู้ให้บริการจะอ้างอิงประเภทและแอตทริบิวต์ในนโยบายสาธารณะได้ ประเภทต่างๆ จะมีการระบุเวอร์ชันตาม PLATFORM_SEPOLICY_VERSION
และนโยบายเวอร์ชันดังกล่าวจะรวมอยู่ในนโยบายของผู้ให้บริการ นโยบายเดิมจะรวมอยู่ในพาร์ติชัน system_ext และ product แต่ละพาร์ติชัน
นโยบายส่วนตัวมีประเภท สิทธิ์ และแอตทริบิวต์สำหรับ system_ext เท่านั้นและสำหรับผลิตภัณฑ์เท่านั้น ซึ่งจำเป็นสำหรับฟังก์ชันการทำงานของพาร์ติชัน system_ext และผลิตภัณฑ์ นโยบายส่วนตัวจะมองไม่เห็นผู้ให้บริการ ซึ่งหมายความว่ากฎเหล่านี้เป็นกฎภายในและอนุญาตให้แก้ไขได้
การแมป system_ext และผลิตภัณฑ์
system_ext และ product ได้รับอนุญาตให้ส่งออกประเภทสาธารณะที่กําหนดไปยังผู้ให้บริการ อย่างไรก็ตาม แต่ละพาร์ทเนอร์มีหน้าที่รับผิดชอบในการรักษาความเข้ากันได้ พาร์ทเนอร์สามารถระบุไฟล์การแมปของตนเองเพื่อใช้แมปแอตทริบิวต์เวอร์ชันของเวอร์ชันก่อนหน้ากับประเภทที่เฉพาะเจาะจงซึ่งใช้ในนโยบายความปลอดภัยสาธารณะปัจจุบัน เพื่อให้เข้ากันได้
- หากต้องการติดตั้งไฟล์การแมปสําหรับ 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