การสร้างนโยบาย SELinux

บทความนี้ครอบคลุมถึงวิธีการสร้างนโยบาย 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 :
      • chkcon : ตรวจสอบว่าบริบทความปลอดภัยถูกต้องสำหรับนโยบายไบนารีที่กำหนด (ปฏิบัติการโฮสต์)
      • libsepol : ไลบรารี SELinux สำหรับจัดการนโยบายความปลอดภัยไบนารี (โฮสต์สแตติก/ไลบรารีที่ใช้ร่วมกัน, ไลบรารีสแตติกเป้าหมาย)
    • 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
รูปที่ 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 บนอุปกรณ์
    รูปภาพนี้แสดงไฟล์ที่สร้างไฟล์นโยบาย SELinux สำหรับ Android 7.x
    รูปที่ 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

    นโยบาย 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 บนพาร์ติชันที่เกี่ยวข้อง ขั้นตอนได้แก่:

    1. การแปลงนโยบายเป็นรูปแบบ SELinux Common Intermediate Language (CIL) โดยเฉพาะ:
      1. นโยบายแพลตฟอร์มสาธารณะ (ระบบ + system_ext + ผลิตภัณฑ์)
      2. นโยบายเอกชน+สาธารณะรวมกัน
      3. นโยบายสาธารณะ + ผู้ขาย และ BOARD_SEPOLICY_DIRS
    2. การกำหนดเวอร์ชันนโยบายที่จัดทำโดยสาธารณะโดยเป็นส่วนหนึ่งของนโยบายผู้ขาย ดำเนินการโดยใช้นโยบาย CIL สาธารณะที่สร้างขึ้นเพื่อแจ้งนโยบายสาธารณะ + ผู้ขาย + BOARD_SEPOLICY_DIRS ที่รวมไว้ว่าส่วนใดจะต้องเปลี่ยนเป็นคุณลักษณะที่จะเชื่อมโยงกับนโยบายแพลตฟอร์ม
    3. การสร้างไฟล์การแมปที่เชื่อมโยงแพลตฟอร์มและส่วนของผู้ขาย ในตอนแรก นี่เป็นเพียงการเชื่อมโยงประเภทจากนโยบายสาธารณะกับคุณลักษณะที่เกี่ยวข้องในนโยบายผู้ขาย หลังจากนั้นจะจัดเตรียมพื้นฐานสำหรับไฟล์ที่เก็บรักษาไว้ในเวอร์ชันแพลตฟอร์มในอนาคต ซึ่งช่วยให้สามารถใช้งานร่วมกับนโยบายของผู้จำหน่ายที่กำหนดเป้าหมายเวอร์ชันแพลตฟอร์มนี้
    4. การรวมไฟล์นโยบาย (อธิบายทั้งบนอุปกรณ์และโซลูชันที่คอมไพล์แล้ว)
      1. รวมการทำแผนที่ แพลตฟอร์ม และนโยบายผู้ขาย
      2. คอมไพล์ไฟล์นโยบายไบนารีเอาต์พุต

    นโยบาย 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 สำหรับรายละเอียดเพิ่มเติม