การสร้างนโยบาย 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 การแยกนโยบาย : การกำหนดค่านโยบายหลักของ 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 บนอุปกรณ์:

ภาพนี้แสดงลอจิกการสร้าง 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

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

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

    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 hashes ของไฟล์ 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 สำหรับรายละเอียดเพิ่มเติม