บทความนี้ครอบคลุมถึงวิธีการสร้างนโยบาย 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
การแยกนโยบาย : การกำหนดค่านโยบายหลักของ Android SELinux รวมถึงบริบทและไฟล์นโยบาย ตรรกะการสร้างการแยกตัวที่สำคัญอยู่ที่นี่ด้วย (system/sepolicy/Android.mk
)
สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับไฟล์ใน system/sepolicy
Implementing SELinux
Android 7.0 และเก่ากว่า
ส่วนนี้ครอบคลุมถึงวิธีการสร้างนโยบาย SELinux ใน Android 7.x และรุ่นก่อนหน้า
การสร้างนโยบาย SELinux
นโยบาย SELinux ถูกสร้างขึ้นโดยการรวมนโยบาย AOSP หลักเข้ากับการปรับแต่งเฉพาะอุปกรณ์ นโยบายที่รวมกันจะถูกส่งไปยังคอมไพเลอร์นโยบายและตัวตรวจสอบต่างๆ การปรับแต่งเฉพาะอุปกรณ์ทำได้โดยใช้ตัวแปร BOARD_SEPOLICY_DIRS
ที่กำหนดไว้ในไฟล์ Boardconfig.mk
เฉพาะอุปกรณ์ ตัวแปร build ส่วนกลางนี้มีรายการไดเร็กทอรีที่ระบุลำดับการค้นหาไฟล์นโยบายเพิ่มเติม
ตัวอย่างเช่น ผู้จำหน่าย 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
บนอุปกรณ์:

ไฟล์ 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
สำหรับรายละเอียดเพิ่มเติม โปรดดูที่ Implementing SELinux
การเริ่มต้น SELinux
เมื่อระบบเริ่มทำงาน SELinux จะอยู่ในโหมดอนุญาต (และไม่ได้อยู่ในโหมดบังคับใช้) กระบวนการ init ทำงานต่อไปนี้:
- โหลดไฟล์
sepolicy
จาก ramdisk เข้าสู่เคอร์เนลผ่าน/sys/fs/selinux/load
- สลับ SELinux เป็นโหมดบังคับใช้
- รัน
re-exec()
เพื่อใช้กฎโดเมน SELinux กับตัวมันเอง
เพื่อลดระยะเวลาบูต ให้ดำเนินการ re-exec()
ในกระบวนการ init
โดยเร็วที่สุด
Android 8.0 ขึ้นไป
ใน Android 8.0 นโยบาย SELinux จะแบ่งออกเป็นส่วนประกอบแพลตฟอร์มและผู้จำหน่ายเพื่ออนุญาตการอัปเดตนโยบายแพลตฟอร์ม/ผู้จำหน่ายอิสระในขณะที่ยังคงความเข้ากันได้
การแยกตัวออกจากแพลตฟอร์มจะแบ่งออกเป็นส่วน ๆ ของแพลตฟอร์มและส่วนสาธารณะของแพลตฟอร์มเพื่อส่งออกประเภทและคุณลักษณะเฉพาะไปยังผู้เขียนนโยบายของผู้ขาย ประเภท/แอตทริบิวต์สาธารณะของแพลตฟอร์มรับประกันว่าจะได้รับการรักษาเป็น API ที่เสถียรสำหรับเวอร์ชันแพลตฟอร์มที่กำหนด ความเข้ากันได้กับประเภท/แอตทริบิวต์สาธารณะของแพลตฟอร์มก่อนหน้าสามารถรับประกันได้หลายเวอร์ชันโดยใช้ไฟล์การแมปแพลตฟอร์ม
แพลตฟอร์ม sepolicy สาธารณะ
การแยกย่อยสาธารณะของแพลตฟอร์มรวมถึงทุกอย่างที่กำหนดไว้ภายใต้ system/sepolicy/public
แพลตฟอร์มสามารถถือว่าประเภทและแอตทริบิวต์ที่กำหนดภายใต้นโยบายสาธารณะเป็น API ที่เสถียรสำหรับรุ่นแพลตฟอร์มที่กำหนด นี้เป็นส่วนหนึ่งของการแบ่งแยกที่ส่งออกโดยแพลตฟอร์มที่นักพัฒนานโยบายผู้ขาย (เช่นอุปกรณ์) อาจเขียนนโยบายเฉพาะอุปกรณ์เพิ่มเติม
ประเภทมีการกำหนดเวอร์ชันตามเวอร์ชันของนโยบายที่เขียนไฟล์ของผู้ขาย ซึ่งกำหนดโดยตัวแปรบิวด์ PLATFORM_SEPOLICY_VERSION
นโยบายสาธารณะที่มีการกำหนดเวอร์ชันจะรวมอยู่ในนโยบายของผู้จัดจำหน่ายและ (ในรูปแบบเดิม) ในนโยบายแพลตฟอร์ม ดังนั้น นโยบายขั้นสุดท้ายจึงรวมถึงนโยบายแพลตฟอร์มส่วนตัว การแยกสาธารณะของแพลตฟอร์มปัจจุบัน นโยบายเฉพาะอุปกรณ์ และนโยบายสาธารณะเวอร์ชันที่สอดคล้องกับเวอร์ชันของแพลตฟอร์มที่ใช้เขียนนโยบายด้านอุปกรณ์
แพลตฟอร์ม sepolicy ส่วนตัว
การแยกตัวของแพลตฟอร์มส่วนตัวรวมถึงทุกอย่างที่กำหนดไว้ภายใต้ /system/sepolicy/private
นโยบายส่วนนี้สร้างประเภทเฉพาะแพลตฟอร์ม สิทธิ์ และแอตทริบิวต์ที่จำเป็นสำหรับฟังก์ชันการทำงานของแพลตฟอร์ม สิ่งเหล่านี้จะไม่ถูกส่งออกไปยังผู้เขียนนโยบายของ vendor/device
ผู้เขียนนโยบายที่ไม่ใช่แพลตฟอร์มต้องไม่เขียนส่วนขยายนโยบายตามประเภท/แอตทริบิวต์/กฎที่กำหนดไว้ในการแบ่งแยกส่วนตัวของแพลตฟอร์ม นอกจากนี้ กฎเหล่านี้ได้รับอนุญาตให้แก้ไขหรืออาจหายไปโดยเป็นส่วนหนึ่งของการอัปเดตเฉพาะเฟรมเวิร์ก
การทำแผนที่ส่วนตัวของแพลตฟอร์ม
การทำแผนที่ส่วนตัวของแพลตฟอร์มรวมถึงแถลงการณ์นโยบายที่แมปแอตทริบิวต์ที่แสดงในนโยบายสาธารณะของแพลตฟอร์มของรุ่นแพลตฟอร์มก่อนหน้ากับประเภทที่เป็นรูปธรรมที่ใช้ในการแยกย่อยสาธารณะของแพลตฟอร์มปัจจุบัน สิ่งนี้ทำให้มั่นใจได้ว่านโยบายผู้จำหน่ายที่เขียนขึ้นตามแอตทริบิวต์สาธารณะของแพลตฟอร์มจากเวอร์ชันการแยกย่อยสาธารณะของแพลตฟอร์มก่อนหน้าจะยังคงทำงานต่อไป การกำหนดเวอร์ชันจะขึ้นอยู่กับตัวแปรบิลด์ PLATFORM_SEPOLICY_VERSION
ที่ตั้งค่าไว้ใน AOSP สำหรับเวอร์ชันแพลตฟอร์มที่กำหนด มีไฟล์การแมปแยกกันสำหรับแต่ละเวอร์ชันของแพลตฟอร์มก่อนหน้าซึ่งแพลตฟอร์มนี้คาดว่าจะยอมรับนโยบายของผู้ขาย สำหรับรายละเอียดเพิ่มเติม โปรดดูที่ ความเข้ากันได้
Android 11 ขึ้นไป
system_ext และการแยกส่วนผลิตภัณฑ์
ใน Android 11 จะมีการเพิ่มนโยบาย system_ext และนโยบายผลิตภัณฑ์ เช่นเดียวกับการแบ่งแยกแพลตฟอร์ม นโยบาย system_ext และนโยบายผลิตภัณฑ์ถูกแบ่งออกเป็นนโยบายสาธารณะและนโยบายส่วนตัว
นโยบายสาธารณะถูกส่งออกไปยังผู้จัดจำหน่าย ประเภทและแอตทริบิวต์จะกลายเป็น API ที่เสถียร และนโยบายผู้ขายสามารถอ้างอิงถึงประเภทและแอตทริบิวต์ในนโยบายสาธารณะได้ ประเภทมีการกำหนดเวอร์ชันตาม PLATFORM_SEPOLICY_VERSION
และนโยบายที่มีการกำหนดเวอร์ชันจะรวมอยู่ในนโยบายของผู้จัดจำหน่าย นโยบายดั้งเดิมรวมอยู่ในแต่ละพาร์ติชัน system_ext และพาร์ติชันผลิตภัณฑ์
นโยบายส่วนตัวประกอบด้วยประเภท system_ext-only และ product-only สิทธิ์และแอตทริบิวต์ที่จำเป็นสำหรับการทำงานของ system_ext และพาร์ติชันผลิตภัณฑ์ นโยบายส่วนบุคคลจะไม่ปรากฏแก่ผู้ขาย ซึ่งหมายความว่ากฎเหล่านี้เป็นกฎภายในและได้รับอนุญาตให้แก้ไขได้
system_ext และการทำแผนที่ผลิตภัณฑ์
system_ext และผลิตภัณฑ์ได้รับอนุญาตให้ส่งออกประเภทสาธารณะที่กำหนดไปยังผู้ขาย อย่างไรก็ตาม ความรับผิดชอบในการรักษาความเข้ากันได้นั้นเป็นของคู่ค้าแต่ละราย เพื่อความเข้ากันได้ พันธมิตรสามารถจัดเตรียมไฟล์การแมปของตนเองซึ่งจับคู่แอตทริบิวต์ที่มีเวอร์ชันของเวอร์ชันก่อนหน้ากับประเภทที่เป็นรูปธรรมที่ใช้ในการแยกย่อยสาธารณะในปัจจุบัน
- ในการติดตั้งไฟล์การแมปสำหรับ 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 Common Intermediate Language (CIL) โดยเฉพาะ:
- นโยบายแพลตฟอร์มสาธารณะ (ระบบ + system_ext + ผลิตภัณฑ์)
- รวมนโยบายส่วนตัว + สาธารณะ
- สาธารณะ + ผู้ขายและนโยบาย
BOARD_SEPOLICY_DIRS
- การกำหนดเวอร์ชันนโยบายที่เผยแพร่โดยสาธารณะซึ่งเป็นส่วนหนึ่งของนโยบายผู้ขาย ดำเนินการโดยใช้นโยบาย CIL สาธารณะที่ผลิตขึ้นเพื่อแจ้งนโยบายสาธารณะ + ผู้ขาย +
BOARD_SEPOLICY_DIRS
ที่รวมกันว่าส่วนใดที่ต้องเปลี่ยนเป็นแอตทริบิวต์ที่จะเชื่อมโยงกับนโยบายแพลตฟอร์ม - การสร้างไฟล์การแมปที่เชื่อมโยงแพลตฟอร์มและส่วนต่างๆ ของผู้จำหน่าย ในขั้นต้น นี่เป็นเพียงการเชื่อมโยงประเภทจากนโยบายสาธารณะกับแอตทริบิวต์ที่เกี่ยวข้องในนโยบายผู้ขาย ในภายหลัง มันยังจะเป็นพื้นฐานสำหรับไฟล์ที่ได้รับการดูแลในเวอร์ชันแพลตฟอร์มในอนาคต ซึ่งช่วยให้เข้ากันได้กับนโยบายของผู้ขายที่กำหนดเป้าหมายเวอร์ชันแพลตฟอร์มนี้
- การรวมไฟล์นโยบาย (อธิบายทั้งบนอุปกรณ์และโซลูชันที่คอมไพล์ล่วงหน้า)
- รวมการทำแผนที่ แพลตฟอร์ม และนโยบายผู้ขาย
- คอมไพล์ไฟล์นโยบายไบนารีเอาต์พุต
- ทั้ง
/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
หรือทั้งสองมีอยู่และเหมือนกัน
การสร้างนโยบาย SELinux
นโยบาย SELinux ใน Android 8.0 สร้างขึ้นจากการรวมชิ้นส่วนจาก /system
และ /vendor
ตรรกะสำหรับการตั้งค่านี้อย่างเหมาะสมอยู่ใน /platform/system/sepolicy/Android.mk
นโยบายมีอยู่ในสถานที่ต่อไปนี้:
ที่ตั้ง | ประกอบด้วย |
---|---|
system/sepolicy/public | API การแยกตัวของแพลตฟอร์ม |
system/sepolicy/private | รายละเอียดการใช้งานแพลตฟอร์ม (ผู้ขายสามารถละเว้นได้) |
system/sepolicy/vendor | ไฟล์นโยบายและบริบทที่ผู้ขายสามารถใช้ได้ (ผู้ขายสามารถละเว้นได้หากต้องการ) |
BOARD_SEPOLICY_DIRS | การแยกตัวของผู้ขาย |
BOARD_ODM_SEPOLICY_DIRS (Android 9 ขึ้นไป) | การแยกตัวของ Odm |
SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS (Android 11 ขึ้นไป) | API การแยกตัวของ System_ext |
SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS (Android 11 ขึ้นไป) | รายละเอียดการใช้งาน System_ext (ผู้ขายสามารถละเว้นได้) |
PRODUCT_PUBLIC_SEPOLICY_DIRS (แอนดรอยด์ 11 ขึ้นไป) | API การแยกตัวของผลิตภัณฑ์ |
PRODUCT_PRIVATE_SEPOLICY_DIRS (แอนดรอยด์ 11 ขึ้นไป) | รายละเอียดการใช้งานผลิตภัณฑ์ (ผู้ขายสามารถละเว้นได้) |
ระบบบิลด์ใช้นโยบายนี้และสร้างส่วนประกอบของระบบ, system_ext, ผลิตภัณฑ์, ผู้จัดจำหน่าย และนโยบาย odm บนพาร์ติชันที่เกี่ยวข้อง ขั้นตอนรวมถึง:
นโยบาย 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 hashes ของไฟล์ CIL อินพุต ขณะรันไทม์ init
จะตรวจสอบว่าไฟล์นโยบายใดได้รับการอัปเดตโดยเปรียบเทียบแฮช หากไม่มีอะไรเปลี่ยนแปลง init
จะโหลดนโยบายที่คอมไพล์ล่วงหน้า ถ้าไม่เช่นนั้น init
จะคอมไพล์ทันทีและใช้แทนการคอมไพล์ล่วงหน้า
โดยเฉพาะอย่างยิ่ง นโยบายที่คอมไพล์ล่วงหน้าจะใช้หากตรงตามเงื่อนไขต่อไปนี้ทั้งหมด ที่นี่ {partition}
แสดงถึงพาร์ติชันที่มีนโยบายที่คอมไพล์ล่วงหน้าแล้ว: vendor
หรือ odm
หากข้อใดข้อหนึ่งแตกต่างกัน init
จะกลับไปที่พาธการคอมไพล์บนอุปกรณ์ ดู system/core/init/selinux.cpp
สำหรับรายละเอียดเพิ่มเติม