บทความนี้ครอบคลุมถึงวิธีการสร้างนโยบาย 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
: การกำหนดค่านโยบาย Core Android SELinux รวมถึงบริบทและไฟล์นโยบาย ตรรกะการสร้าง sepolicy หลักก็อยู่ที่นี่เช่นกัน (system/sepolicy/Android.mk
)
สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับไฟล์ใน system/sepolicy
Implementing SELinux
Android 7.0 และรุ่นก่อนหน้า
ส่วนนี้ครอบคลุมถึงวิธีการสร้างนโยบาย SELinux ใน Android 7.x และรุ่นก่อนหน้า
การสร้างนโยบาย SELinux
นโยบาย 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
บนอุปกรณ์:
![รูปภาพนี้แสดงลอจิกการสร้าง SELinux สำหรับ Android 7.x](https://source.android.google.cn/static/docs/security/features/selinux/images/n-selinux-build-logic.png?authuser=2&hl=th)
ไฟล์ 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 จะอยู่ในโหมดอนุญาต (และไม่อยู่ในโหมดบังคับใช้) กระบวนการเริ่มต้นดำเนินงานต่อไปนี้:
- โหลดไฟล์
sepolicy
จาก ramdisk ลงในเคอร์เนลผ่าน/sys/fs/selinux/load
- สลับ SELinux เป็นโหมดบังคับใช้
- เรียกใช้
re-exec()
เพื่อใช้กฎโดเมน SELinux กับตัวมันเอง
หากต้องการย่นระยะเวลาการบูต ให้ดำเนินการ re-exec()
ในกระบวนการ init
โดยเร็วที่สุด
Android 8.0 และสูงกว่า
ใน Android 8.0 นโยบาย SELinux จะแบ่งออกเป็นแพลตฟอร์มและส่วนประกอบของผู้จำหน่ายเพื่อให้สามารถอัปเดตนโยบายแพลตฟอร์ม/ผู้จำหน่ายอิสระในขณะที่ยังคงความเข้ากันได้
นโยบายความเป็นส่วนตัวของแพลตฟอร์มจะถูกแบ่งออกเป็นส่วนส่วนตัวของแพลตฟอร์มและส่วนสาธารณะของแพลตฟอร์มเพื่อส่งออกประเภทและคุณลักษณะเฉพาะไปยังผู้เขียนนโยบายของผู้ขาย ประเภท/คุณลักษณะสาธารณะของแพลตฟอร์มรับประกันว่าจะคงไว้เป็น API ที่เสถียรสำหรับเวอร์ชันแพลตฟอร์มที่กำหนด ความเข้ากันได้กับประเภท/คุณลักษณะสาธารณะของแพลตฟอร์มก่อนหน้านี้สามารถรับประกันได้สำหรับหลายเวอร์ชันโดยใช้ไฟล์การแมปแพลตฟอร์ม
นโยบายความเป็นส่วนตัวสาธารณะของแพลตฟอร์ม
นโยบายการแยกสาธารณะของแพลตฟอร์มประกอบด้วยทุกสิ่งที่กำหนดไว้ภายใต้ system/sepolicy/public
แพลตฟอร์มสามารถถือว่าประเภทและคุณลักษณะที่กำหนดภายใต้นโยบายสาธารณะนั้นเป็น API ที่เสถียรสำหรับเวอร์ชันแพลตฟอร์มที่กำหนด นี่เป็นส่วนหนึ่งของนโยบาย sepolicy ที่ส่งออกโดยแพลตฟอร์มที่ผู้พัฒนานโยบายของผู้จำหน่าย (เช่น อุปกรณ์) อาจเขียนนโยบายเฉพาะอุปกรณ์เพิ่มเติม
ประเภทจะได้รับการกำหนดเวอร์ชันตามเวอร์ชันของนโยบายที่ไฟล์ของผู้จำหน่ายถูกเขียนทับ ซึ่งกำหนดโดยตัวแปรบิลด์ PLATFORM_SEPOLICY_VERSION
นโยบายสาธารณะเวอร์ชันจะถูกรวมเข้ากับนโยบายผู้ขายและ (ในรูปแบบดั้งเดิม) ในนโยบายแพลตฟอร์ม ดังนั้น นโยบายขั้นสุดท้ายจึงรวมถึงนโยบายแพลตฟอร์มส่วนตัว นโยบายการแยกสาธารณะของแพลตฟอร์มปัจจุบัน นโยบายเฉพาะอุปกรณ์ และนโยบายสาธารณะเวอร์ชันที่สอดคล้องกับเวอร์ชันแพลตฟอร์มที่ใช้เขียนนโยบายด้านอุปกรณ์
นโยบายความเป็นส่วนตัวของแพลตฟอร์ม
แพลตฟอร์ม sepolicy ส่วนตัวรวมทุกอย่างที่กำหนดไว้ภายใต้ /system/sepolicy/private
นโยบายส่วนนี้สร้างประเภทเฉพาะแพลตฟอร์ม สิทธิ์ และแอตทริบิวต์ที่จำเป็นสำหรับฟังก์ชันการทำงานของแพลตฟอร์ม สิ่งเหล่านี้จะไม่ถูกส่งออกไปยัง vendor/device
ผู้เขียนนโยบายที่ไม่ใช่แพลตฟอร์มจะต้องไม่เขียนส่วนขยายนโยบายตามประเภท/คุณลักษณะ/กฎที่กำหนดไว้ในนโยบายความเป็นส่วนตัวของแพลตฟอร์ม นอกจากนี้ กฎเหล่านี้ยังได้รับอนุญาตให้แก้ไขหรืออาจหายไปโดยเป็นส่วนหนึ่งของการอัปเดตเฉพาะเฟรมเวิร์ก
การทำแผนที่ส่วนตัวของแพลตฟอร์ม
การทำแผนที่ส่วนตัวของแพลตฟอร์มประกอบด้วยคำแถลงนโยบายที่แมปคุณลักษณะที่เปิดเผยในนโยบายสาธารณะของแพลตฟอร์มของเวอร์ชันก่อนหน้ากับประเภทที่เป็นรูปธรรมที่ใช้ในนโยบายสาธารณะของแพลตฟอร์มปัจจุบัน สิ่งนี้ทำให้แน่ใจได้ว่านโยบายผู้ขายที่เขียนตามคุณลักษณะสาธารณะของแพลตฟอร์มจากเวอร์ชันนโยบายการแยกสาธารณะของแพลตฟอร์มก่อนหน้านี้ยังคงทำงานต่อไป การกำหนดเวอร์ชันจะขึ้นอยู่กับตัวแปรบิลด์ PLATFORM_SEPOLICY_VERSION
ที่ตั้งค่าใน AOSP สำหรับเวอร์ชันแพลตฟอร์มที่ระบุ มีไฟล์การแมปแยกต่างหากสำหรับแพลตฟอร์มเวอร์ชันก่อนหน้าแต่ละเวอร์ชัน ซึ่งแพลตฟอร์มนี้คาดว่าจะยอมรับนโยบายของผู้ขาย สำหรับรายละเอียดเพิ่มเติม โปรดดูที่ ความเข้ากันได้
Android 11 และสูงกว่า
system_ext และ sepolicy ของผลิตภัณฑ์
ใน Android 11 จะมีการเพิ่มนโยบาย system_ext และนโยบายผลิตภัณฑ์ เช่นเดียวกับ sepolicy ของแพลตฟอร์ม นโยบาย 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 ของ sepolicy ของแพลตฟอร์ม |
system/sepolicy/private | รายละเอียดการใช้งานแพลตฟอร์ม (ผู้ขายสามารถเพิกเฉยได้) |
system/sepolicy/vendor | ไฟล์นโยบายและบริบทที่ผู้ขายสามารถใช้ได้ (ผู้ขายสามารถเพิกเฉยได้หากต้องการ) |
BOARD_SEPOLICY_DIRS | นโยบายการแยกตัวของผู้ขาย |
BOARD_ODM_SEPOLICY_DIRS (Android 9 ขึ้นไป) | นโยบายการแยกตัวของ Odm |
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 การแยกส่วนของผลิตภัณฑ์ |
PRODUCT_PRIVATE_SEPOLICY_DIRS (Android 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 ของไฟล์ CIL อินพุต ณ รันไทม์ init
จะตรวจสอบว่าไฟล์นโยบายใด ๆ ได้รับการอัปเดตหรือไม่โดยการเปรียบเทียบแฮช หากไม่มีการเปลี่ยนแปลงใดๆ init
โหลดนโยบายที่คอมไพล์ไว้แล้ว ถ้าไม่เช่นนั้น init
คอมไพล์ทันทีและใช้มันแทนคอมไพล์ที่คอมไพล์แล้ว
โดยเฉพาะอย่างยิ่ง นโยบายที่คอมไพล์ล่วงหน้าจะถูกใช้หากตรงตามเงื่อนไขต่อไปนี้ทั้งหมด ที่นี่ {partition}
แสดงถึงพาร์ติชันที่มีนโยบายที่คอมไพล์ไว้แล้ว: vendor
หรือ odm
หากข้อใดข้อหนึ่งแตกต่าง init
จะถอยกลับไปยังเส้นทางการคอมไพล์บนอุปกรณ์ ดู system/core/init/selinux.cpp
สำหรับรายละเอียดเพิ่มเติม