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

หน้านี้จะอธิบายวิธีสร้างนโยบาย SELinux นโยบาย SELinux สร้างขึ้นจากการรวมกันของนโยบาย AOSP หลัก (แพลตฟอร์ม) และนโยบายเฉพาะอุปกรณ์ (ผู้ให้บริการ) ขั้นตอนการสร้างนโยบาย SELinux สำหรับ Android 4.4 ถึง Android 7.0 จะรวมชิ้นส่วน sepolicy ทั้งหมด แล้วสร้างไฟล์แบบ Monolithic ในไดเรกทอรีราก ซึ่งหมายความว่าผู้ให้บริการ SoC และผู้ผลิต ODM ต้องแก้ไข boot.img (สำหรับอุปกรณ์ที่ไม่ใช่ A/B) หรือ system.img (สำหรับอุปกรณ์ A/B) ทุกครั้งที่มีการแก้ไขนโยบาย

ใน Android 8.0 ขึ้นไป นโยบายแพลตฟอร์มและนโยบายของผู้ให้บริการจะสร้างแยกกัน SoC และ OEM สามารถอัปเดตส่วนของนโยบาย สร้างอิมเมจ (เช่น vendor.img และ boot.img) จากนั้นอัปเดตอิมเมจเหล่านั้นโดยไม่ขึ้นอยู่กับการอัปเดตแพลตฟอร์ม

อย่างไรก็ตาม เนื่องจากไฟล์นโยบาย SELinux แบบแยกส่วนจะจัดเก็บไว้ในพาร์ติชัน /vendor กระบวนการ init จึงต้องติดตั้งพาร์ติชัน system และ vendor ก่อนหน้านี้เพื่อให้สามารถอ่านไฟล์ SELinux จากพาร์ติชันเหล่านั้นและผสานรวม กับไฟล์ SELinux หลักในไดเรกทอรี system (ก่อนที่จะโหลดลงใน เคอร์เนล)

ไฟล์แหล่งข้อมูล

ตรรกะสำหรับการสร้าง SELinux อยู่ในไฟล์ต่อไปนี้

  • external/selinux: โปรเจ็กต์ SELinux ภายนอก ใช้เพื่อ สร้างยูทิลิตีบรรทัดคำสั่ง HOST เพื่อคอมไพล์นโยบายและป้ายกำกับ SELinux
    • external/selinux/libselinux: Android ใช้เฉพาะชุดย่อย ของโปรเจ็กต์ libselinux ภายนอกร่วมกับการปรับแต่งบางอย่าง ที่เฉพาะเจาะจงสำหรับ Android โปรดดูรายละเอียดที่ external/selinux/README.android
    • external/selinux/libsepol:
      • chkcon: Determine if a security context is valid for a given binary policy (host executable).
      • libsepol: ไลบรารี SELinux สำหรับการจัดการไบนารี นโยบายความปลอดภัย (ไลบรารีแบบคงที่/แบบแชร์ของโฮสต์ ไลบรารีแบบคงที่ของเป้าหมาย)
    • external/selinux/checkpolicy: SELinux policy compiler (host executables: checkpolicy, checkmodule, and dispol). Depends on libsepol.
  • system/sepolicy: การกำหนดค่าหลักของนโยบาย SELinux ของ Android รวมถึงบริบทและไฟล์นโยบาย ตรรกะการสร้าง sepolicy หลัก ก็อยู่ที่นี่ด้วย (system/sepolicy/Android.mk)

ดูรายละเอียดเพิ่มเติมเกี่ยวกับไฟล์ใน system/sepolicy ได้ที่ ไฟล์คีย์

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 ในอุปกรณ์

ตรรกะการสร้าง 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 จะอยู่ในโหมดที่อนุญาต (และไม่ได้อยู่ในโหมดบังคับ) กระบวนการ init จะดำเนินการต่อไปนี้

  • โหลดไฟล์ sepolicy จาก Ramdisk ลงในเคอร์เนลผ่าน /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.bp

นโยบายนี้อยู่ในตำแหน่งต่อไปนี้

ตำแหน่ง ประกอบด้วย
system/sepolicy/public Platform sepolicy API
system/sepolicy/private รายละเอียดการติดตั้งใช้งานแพลตฟอร์ม (ผู้ให้บริการไม่ต้องสนใจ)
system/sepolicy/vendor ไฟล์นโยบายและบริบทที่ผู้ให้บริการใช้ได้ (ผู้ให้บริการจะละเว้นก็ได้)
BOARD_SEPOLICY_DIRS sepolicy ของผู้ให้บริการ
BOARD_ODM_SEPOLICY_DIRS (Android 9 ขึ้นไป) sepolicy ของ ODM
SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS (Android 11 ขึ้นไป) system_ext sepolicy API
SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS (Android 11 ขึ้นไป) system_ext รายละเอียดการติดตั้งใช้งาน (ผู้ให้บริการไม่ต้องสนใจ)
PRODUCT_PUBLIC_SEPOLICY_DIRS (Android 11 ขึ้นไป) Product sepolicy API
PRODUCT_PRIVATE_SEPOLICY_DIRS (Android 11 ขึ้นไป) รายละเอียดการติดตั้งใช้งานผลิตภัณฑ์ (ผู้ให้บริการไม่ต้องสนใจ)

ระบบบิลด์จะใช้นโยบายนี้และสร้างคอมโพเนนต์นโยบาย system, system_ext, product, vendor และ odm ในพาร์ติชันที่เกี่ยวข้อง ขั้นตอนมีดังนี้

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

นโยบายความปลอดภัยสาธารณะของแพลตฟอร์ม

sepolicy สาธารณะของแพลตฟอร์มมีทุกอย่างที่กำหนดไว้ใน system/sepolicy/public แพลตฟอร์มสามารถถือว่าประเภทและ แอตทริบิวต์ที่กำหนดไว้ภายใต้นโยบายสาธารณะเป็น API ที่เสถียรสำหรับแพลตฟอร์มเวอร์ชันที่กำหนด ซึ่งเป็นส่วนหนึ่งของ sepolicy ที่แพลตฟอร์มส่งออก ซึ่งนักพัฒนาด้านนโยบายของผู้ให้บริการ (นั่นคือ อุปกรณ์) สามารถเขียนนโยบายเพิ่มเติม ที่เฉพาะเจาะจงสำหรับอุปกรณ์ได้

ประเภทจะมีการควบคุมเวอร์ชันตามเวอร์ชันของนโยบายที่เขียนไฟล์ ของผู้ให้บริการ โดยกำหนดโดยPLATFORM_SEPOLICY_VERSION ตัวแปรบิลด์ จากนั้นจะรวมนโยบายสาธารณะที่กำหนดเวอร์ชันไว้กับ นโยบายของผู้ให้บริการและ (ในรูปแบบเดิม) ในนโยบายแพลตฟอร์ม ดังนั้น นโยบายสุดท้ายจึงรวมถึงนโยบายแพลตฟอร์มส่วนตัว นโยบายสาธารณะของ sepolicy ของแพลตฟอร์มปัจจุบัน นโยบายเฉพาะของอุปกรณ์ และนโยบายสาธารณะที่มีการกำหนดเวอร์ชัน ซึ่งสอดคล้องกับเวอร์ชันของแพลตฟอร์มที่ใช้อ้างอิงในการเขียนนโยบายของอุปกรณ์

sepolicy ส่วนตัวของแพลตฟอร์ม

นโยบายความปลอดภัยของแพลตฟอร์มส่วนตัวประกอบด้วยทุกอย่างที่กำหนดไว้ใน /system/sepolicy/private ส่วนนี้ของนโยบายจะกำหนดประเภท สิทธิ์ และแอตทริบิวต์เฉพาะแพลตฟอร์มที่จำเป็นสำหรับฟังก์ชันการทำงานของแพลตฟอร์ม ระบบจะไม่ส่งออกข้อมูลเหล่านี้ไปยังผู้ให้บริการและผู้เขียนนโยบายอุปกรณ์ ผู้เขียนนโยบายที่ไม่ใช่แพลตฟอร์มต้องไม่เขียนส่วนขยายนโยบาย ตามประเภท แอตทริบิวต์ และกฎที่กำหนดไว้ใน sepolicy ส่วนตัวของแพลตฟอร์ม นอกจากนี้ คุณยังแก้ไขกฎเหล่านี้ได้ หรือกฎอาจหายไปเมื่ออัปเดตเฉพาะเฟรมเวิร์ก

การแมปส่วนตัวของแพลตฟอร์ม

การแมปส่วนตัวของแพลตฟอร์มประกอบด้วยข้อความนโยบายที่แมปแอตทริบิวต์ ที่เปิดเผยในนโยบายสาธารณะของแพลตฟอร์มในแพลตฟอร์มเวอร์ชันก่อนหน้ากับ ประเภทที่เฉพาะเจาะจงซึ่งใช้ใน sepolicy สาธารณะของแพลตฟอร์มปัจจุบัน เพื่อให้มั่นใจว่านโยบายของผู้ให้บริการที่เขียนขึ้นโดยอิงตามแอตทริบิวต์สาธารณะของแพลตฟอร์มจาก sepolicy สาธารณะของแพลตฟอร์มเวอร์ชันก่อนหน้าจะยังคงใช้งานได้ การกำหนดเวอร์ชันจะอิงตามPLATFORM_SEPOLICY_VERSIONตัวแปรบิลด์ ที่ตั้งค่าไว้ใน AOSP สำหรับเวอร์ชันแพลตฟอร์มที่กำหนด มีไฟล์การแมปแยกต่างหากสำหรับ แพลตฟอร์มเวอร์ชันก่อนหน้าแต่ละเวอร์ชันซึ่งคาดว่าแพลตฟอร์มนี้จะยอมรับ นโยบายของผู้ให้บริการ ดูรายละเอียดเพิ่มเติมได้ที่ความเข้ากันได้ของนโยบาย

Android 11 ขึ้นไป

ส่วนนี้จะอธิบายวิธีสร้างนโยบาย SELinux ใน Android 11 ขึ้นไป

system_ext และ sepolicy ของผลิตภัณฑ์

ใน Android 11 มีการเพิ่มนโยบาย system_ext และนโยบาย product เช่นเดียวกับนโยบาย sepolicy ของแพลตฟอร์ม system_extนโยบายproductและนโยบายproductจะแบ่งออกเป็น นโยบายสาธารณะและนโยบายส่วนตัว

ระบบจะส่งออกนโยบายสาธารณะไปยังผู้ให้บริการ ประเภทและแอตทริบิวต์จะกลายเป็น API ที่เสถียร และ นโยบายของผู้ให้บริการสามารถอ้างอิงประเภทและแอตทริบิวต์ในนโยบายสาธารณะได้ ประเภทต่างๆ จะ มีการกำหนดเวอร์ชันตาม PLATFORM_SEPOLICY_VERSION และนโยบาย ที่มีการกำหนดเวอร์ชันจะรวมอยู่ในนโยบายของผู้ให้บริการ นโยบายเดิมจะรวมอยู่ในพาร์ติชัน system_ext และ product แต่ละรายการ

นโยบายส่วนตัวมีประเภท สิทธิ์ และ แอตทริบิวต์ที่จำเป็นสำหรับฟังก์ชันการแบ่งพาร์ติชัน system_ext และ product เท่านั้นsystem_extproduct นโยบายส่วนตัวจะไม่แสดงต่อผู้ให้บริการ ซึ่งหมายความว่ากฎเหล่านี้เป็นกฎภายใน และสามารถแก้ไขได้

การแมป system_ext และผลิตภัณฑ์

system_ext และ product ได้รับอนุญาตให้ส่งออกประเภทสาธารณะที่กำหนดไปยัง ผู้ให้บริการ อย่างไรก็ตาม พาร์ทเนอร์แต่ละรายมีหน้าที่รับผิดชอบในการรักษา ความเข้ากันได้ พาร์ทเนอร์สามารถระบุไฟล์การแมปของตนเองเพื่อแมปแอตทริบิวต์ที่มีการกำหนดเวอร์ชันของเวอร์ชันก่อนหน้ากับประเภทที่เฉพาะเจาะจงที่ใช้ใน sepolicy สาธารณะปัจจุบันเพื่อความเข้ากันได้

  • หากต้องการติดตั้งไฟล์การจับคู่สำหรับ system_ext ให้วางไฟล์ CIL ที่มี ข้อมูลการจับคู่ที่ต้องการไว้ใน {SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil จากนั้นเพิ่ม system_ext_{ver}.cil ลงใน PRODUCT_PACKAGES
  • หากต้องการติดตั้งไฟล์การจับคู่สำหรับ product ให้วางไฟล์ CIL ที่มี ข้อมูลการจับคู่ที่ต้องการไว้ใน {PRODUCT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil จากนั้นเพิ่ม product_{ver}.cil ลงใน PRODUCT_PACKAGES

ดูตัวอย่าง ที่เพิ่มไฟล์การแมปของพาร์ติชัน product ของอุปกรณ์ 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