สร้างนโยบาย 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 จึงต้องติดตั้งพาร์ติชันระบบและพาร์ติชันของผู้ให้บริการ ก่อนหน้านี้เพื่อให้สามารถอ่านไฟล์ 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: การกำหนดค่าหลักของนโยบาย SELinux ของ Android รวมถึงบริบทและไฟล์นโยบาย ตรรกะการสร้าง sepolicy หลัก ก็อยู่ที่นี่ด้วย (system/sepolicy/Android.mk)

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

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.mk

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

ตำแหน่ง ประกอบด้วย
system/sepolicy/public API ของ sepolicy ของแพลตฟอร์ม
system/sepolicy/private รายละเอียดการติดตั้งใช้งานแพลตฟอร์ม (ผู้ให้บริการไม่ต้องสนใจ)
system/sepolicy/vendor ไฟล์นโยบายและบริบทที่ผู้ให้บริการใช้ได้ (ผู้ให้บริการจะละเว้นก็ได้หากต้องการ)
BOARD_SEPOLICY_DIRS sepolicy ของผู้ให้บริการ
BOARD_ODM_SEPOLICY_DIRS (Android 9 ขึ้นไป) Odm sepolicy
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 sepolicy ของผลิตภัณฑ์
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. คอมไพล์ไฟล์นโยบายไบนารีเอาต์พุต

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

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

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

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

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

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

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

Android 11 ขึ้นไป

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

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

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

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

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

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

  • หากต้องการติดตั้งไฟล์การแมปสำหรับ 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 ที่คอมไพล์ล่วงหน้า

ก่อนที่ 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