การใช้ SELinux

SELinux ถูกตั้งค่าเป็น default-deny ซึ่งหมายความว่าทุกการเข้าถึงที่มี hook ในเคอร์เนลจะต้องได้รับอนุญาตอย่างชัดเจนจากนโยบาย ซึ่งหมายความว่าไฟล์นโยบายประกอบด้วยข้อมูลจำนวนมากเกี่ยวกับกฎ ประเภท คลาส สิทธิ์ และอื่นๆ การพิจารณา SELinux อย่างครบถ้วนนั้นอยู่นอกขอบเขตของเอกสารนี้ แต่ความเข้าใจในการเขียนกฎของนโยบายเป็นสิ่งสำคัญเมื่อนำอุปกรณ์ Android ใหม่มาใช้ มีข้อมูลมากมายเกี่ยวกับ SELinux อยู่แล้ว ดู เอกสารประกอบ สำหรับแหล่งข้อมูลที่แนะนำ

ไฟล์สำคัญ

ในการเปิดใช้งาน SELinux ให้รวม เคอร์เนล Android ล่าสุด แล้วรวมไฟล์ที่พบในไดเร็กทอรี ระบบ/sepolicy เมื่อคอมไพล์แล้ว ไฟล์เหล่านั้นจะประกอบด้วยนโยบายการรักษาความปลอดภัยของเคอร์เนล SELinux และครอบคลุมระบบปฏิบัติการ Android อัปสตรีม

โดยทั่วไป คุณไม่ควรแก้ไขไฟล์ system/sepolicy โดยตรง ให้เพิ่มหรือแก้ไขไฟล์นโยบายเฉพาะอุปกรณ์ของคุณเองในไดเร็กทอรี /device/ manufacturer / device-name /sepolicy ใน Android 8.0 ขึ้นไป การเปลี่ยนแปลงที่คุณทำกับไฟล์เหล่านี้ควรมีผลกับนโยบายในไดเรกทอรีผู้ขายของคุณเท่านั้น สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับการแยกการแยกดินแดนสาธารณะใน Android 8.0 ขึ้นไป โปรดดูที่ การ ปรับแต่ง SEPolicy ใน Android 8.0+ โดยไม่คำนึงถึงเวอร์ชัน Android คุณยังคงแก้ไขไฟล์เหล่านี้:

ไฟล์นโยบาย

ไฟล์ที่ลงท้ายด้วย *.te คือไฟล์ต้นฉบับของนโยบาย SELinux ซึ่งกำหนดโดเมนและป้ายกำกับ คุณอาจต้องสร้างไฟล์นโยบายใหม่ใน /device/ manufacturer / device-name /sepolicy แต่คุณควรพยายามอัปเดตไฟล์ที่มีอยู่หากทำได้

ไฟล์บริบท

ไฟล์บริบทเป็นที่ที่คุณระบุป้ายกำกับสำหรับวัตถุของคุณ

  • file_contexts กำหนดป้ายกำกับให้กับไฟล์และถูกใช้โดยส่วนประกอบ userspace ต่างๆ เมื่อคุณสร้างนโยบายใหม่ ให้สร้างหรืออัปเดตไฟล์นี้เพื่อกำหนดป้ายกำกับใหม่ให้กับไฟล์ หากต้องการใช้ file_contexts ใหม่ ให้สร้างอิมเมจระบบไฟล์ใหม่ หรือเรียกใช้ restorecon บนไฟล์ที่จะติดป้ายกำกับใหม่ ในการอัพเกรด การเปลี่ยนแปลง file_contexts จะถูกนำไปใช้กับระบบและพาร์ติชันข้อมูลผู้ใช้โดยอัตโนมัติ ซึ่งเป็นส่วนหนึ่งของการอัพเกรด การเปลี่ยนแปลงยังสามารถนำไปใช้โดยอัตโนมัติในการอัพเกรดเป็นพาร์ติชั่นอื่นโดยการเพิ่มการเรียก restorecon_recursive ให้กับ init ของคุณ board .rc ไฟล์หลังจากติดตั้งพาร์ติชั่นแบบอ่าน-เขียนแล้ว
  • genfs_contexts กำหนดป้ายกำกับให้กับระบบไฟล์ เช่น proc หรือ vfat ที่ไม่สนับสนุนแอตทริบิวต์เพิ่มเติม การกำหนดค่านี้ถูกโหลดโดยเป็นส่วนหนึ่งของนโยบายเคอร์เนล แต่การเปลี่ยนแปลงอาจไม่มีผลกับ inodes ในคอร์ จำเป็นต้องรีบูตหรือยกเลิกการต่อเชื่อมและต่อเชื่อมระบบไฟล์ใหม่เพื่อใช้การเปลี่ยนแปลงทั้งหมด ป้ายกำกับเฉพาะอาจถูกกำหนดให้กับการต่อเชื่อมเฉพาะ เช่น vfat โดยใช้ตัวเลือก context=mount ต์
  • property_contexts กำหนดป้ายกำกับให้กับคุณสมบัติของระบบ Android เพื่อควบคุมกระบวนการที่สามารถตั้งค่าได้ การกำหนดค่านี้อ่านโดยกระบวนการ init ในระหว่างการเริ่มต้น
  • service_contexts กำหนดป้ายกำกับให้กับบริการ Binder ของ Android เพื่อควบคุมกระบวนการที่สามารถเพิ่ม (ลงทะเบียน) และค้นหา (ค้นหา) ข้อมูลอ้างอิง Binder สำหรับบริการ การกำหนดค่านี้อ่านโดยกระบวนการ servicemanager ในระหว่างการเริ่มต้น
  • seapp_contexts กำหนดป้ายกำกับให้กับกระบวนการของแอปและไดเร็กทอรี /data/data การกำหนดค่านี้อ่านโดยกระบวนการ zygote ตในการเปิดใช้แอปแต่ละครั้งและโดยการ installd ตั้งระหว่างการเริ่มต้น
  • mac_permissions.xml กำหนดแท็ก seinfo ให้กับแอพตามลายเซ็นและชื่อแพ็คเกจ แท็ก seinfo สามารถใช้เป็นคีย์ในไฟล์ seapp_contexts เพื่อกำหนดป้ายกำกับเฉพาะให้กับแอปทั้งหมดที่มีแท็ก seinfo นั้น การกำหนดค่านี้ถูกอ่านโดย system_server ระหว่างการเริ่มต้น
  • keystore2_key_contexts กำหนดเลเบลให้กับเนมสเปซ Keystore 2.0 เนมสเปซเหล่านี้บังคับใช้โดย keystore2 daemon Keystore ได้จัดเตรียมเนมสเปซที่ใช้ UID/AID ไว้เสมอ Keystore 2.0 ยังบังคับใช้เนมสเปซที่กำหนดโดย sepolicy คำอธิบายโดยละเอียดของรูปแบบและข้อตกลงของไฟล์นี้สามารถพบได้ ที่นี่

BoardConfig.mk makefile

หลังจากแก้ไขหรือเพิ่มไฟล์นโยบายและบริบทแล้ว ให้อัปเดต /device/ manufacturer / device-name /BoardConfig.mk makefile ของคุณเพื่ออ้างอิงไดเร็กทอรีย่อย sepolicy และไฟล์นโยบายใหม่แต่ละไฟล์ สำหรับข้อมูลเพิ่มเติมเกี่ยวกับตัวแปร BOARD_SEPOLICY โปรดดู system/sepolicy/README

BOARD_SEPOLICY_DIRS += \
        <root>/device/manufacturer/device-name/sepolicy

BOARD_SEPOLICY_UNION += \
        genfs_contexts \
        file_contexts \
        sepolicy.te

หลังจากสร้างใหม่ อุปกรณ์ของคุณเปิดใช้งานด้วย SELinux ขณะนี้ คุณสามารถปรับแต่งนโยบาย SELinux ของคุณเพื่อรองรับการเพิ่มระบบปฏิบัติการ Android ของคุณเองตามที่อธิบายไว้ใน Customization หรือตรวจสอบการตั้งค่าที่มีอยู่ตามที่ระบุไว้ใน Validation

เมื่อมีไฟล์นโยบายใหม่และการอัปเดต BoardConfig.mk การตั้งค่านโยบายใหม่จะถูกสร้างขึ้นโดยอัตโนมัติในไฟล์นโยบายเคอร์เนลสุดท้าย สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีการสร้างการแบ่งแยกบนอุปกรณ์ โปรดดูที่ การ สร้างการแยก ตัวออกจากกัน

การดำเนินการ

ในการเริ่มต้นใช้งาน SELinux:

  1. เปิดใช้งาน SELinux ในเคอร์เนล: CONFIG_SECURITY_SELINUX=y
  2. เปลี่ยนพารามิเตอร์ kernel_cmdline หรือ bootconfig เพื่อให้:
    BOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
    หรือ
    BOARD_BOOTCONFIG := androidboot.selinux=permissive
    ใช้สำหรับการพัฒนานโยบายเบื้องต้นสำหรับอุปกรณ์เท่านั้น หลังจากที่คุณมีนโยบายบูตสแตรปเริ่มต้นแล้ว ให้ลบพารามิเตอร์นี้เพื่อให้อุปกรณ์ของคุณบังคับใช้ มิฉะนั้น CTS จะล้มเหลว
  3. บูตระบบโดยอนุญาตและดูว่ามีการปฏิเสธอะไรบ้างในการบู๊ต:
    บน Ubuntu 14.04 หรือใหม่กว่า:
    adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy
    
    บน Ubuntu 12.04:
    adb pull /sys/fs/selinux/policy
    adb logcat -b all | audit2allow -p policy
    
  4. ประเมินผลลัพธ์สำหรับคำเตือนที่คล้ายกับ init: Warning! Service name needs a SELinux domain defined; please fix! ดูการ ตรวจสอบ สำหรับคำแนะนำและเครื่องมือ
  5. ระบุอุปกรณ์และไฟล์ใหม่อื่นๆ ที่ต้องมีป้ายกำกับ
  6. ใช้ป้ายกำกับที่มีอยู่หรือใหม่สำหรับวัตถุของคุณ ดูไฟล์ *_contexts เพื่อดูว่าสิ่งต่าง ๆ ถูกติดป้ายกำกับไว้ก่อนหน้านี้อย่างไร และใช้ความรู้เกี่ยวกับความหมายของป้ายกำกับเพื่อกำหนดสิ่งใหม่ ตามหลักการแล้ว นี่จะเป็นป้ายกำกับที่มีอยู่ซึ่งจะเข้ากับนโยบาย แต่บางครั้งอาจต้องใช้ป้ายกำกับใหม่ และจำเป็นต้องมีกฎสำหรับการเข้าถึงป้ายกำกับนั้น เพิ่มป้ายกำกับของคุณลงในไฟล์บริบทที่เหมาะสม
  7. ระบุโดเมน/กระบวนการที่ควรมีโดเมนความปลอดภัยของตนเอง คุณอาจต้องเขียนนโยบายใหม่ทั้งหมดสำหรับแต่ละนโยบาย บริการทั้งหมดที่เกิดจาก init ควรมีบริการของตัวเอง คำสั่งต่อไปนี้ช่วยเปิดเผยคำสั่งที่ยังคงทำงานอยู่ (แต่บริการทั้งหมดจำเป็นต้องได้รับการดูแล):
    adb shell su -c ps -Z | grep init
    
    adb shell su -c dmesg | grep 'avc: '
    
  8. init. device .rc เพื่อระบุโดเมนใดๆ ที่ไม่มีประเภทโดเมน ให้โดเมนแก่พวกเขา ตั้งแต่เนิ่นๆ ในกระบวนการพัฒนาของคุณ เพื่อหลีกเลี่ยงการเพิ่มกฎในการเริ่ม init init กฎที่อยู่ในนโยบายของพวกเขาเอง
  9. ตั้งค่า BOARD_CONFIG.mk เพื่อใช้ตัวแปร BOARD_SEPOLICY_* ดู README ใน system/sepolicy สำหรับรายละเอียดเกี่ยวกับการตั้งค่านี้
  10. ตรวจสอบการเริ่มต้น device .rc และ fstab ไฟล์ device และตรวจสอบให้แน่ใจว่าการใช้การ mount นต์ทุกครั้งสอดคล้องกับระบบไฟล์ที่มีป้ายกำกับอย่างเหมาะสม หรือระบุตัวเลือกการ context= mount
  11. ผ่านการปฏิเสธแต่ละครั้งและสร้างนโยบาย SELinux เพื่อจัดการแต่ละข้ออย่างเหมาะสม ดูตัวอย่างในการ ปรับแต่ง

คุณควรเริ่มต้นด้วยนโยบายใน AOSP แล้วสร้างตามนโยบายสำหรับการปรับแต่งของคุณเอง สำหรับข้อมูลเพิ่มเติมเกี่ยวกับกลยุทธ์นโยบายและดูขั้นตอนเหล่านี้อย่างละเอียดยิ่งขึ้น โปรดดูที่ การเขียนนโยบาย SELinux

กรณีการใช้งาน

ต่อไปนี้คือตัวอย่างเฉพาะของการใช้ประโยชน์จากช่องโหว่ที่ควรพิจารณาเมื่อสร้างซอฟต์แวร์ของคุณเองและนโยบาย SELinux ที่เกี่ยวข้อง:

Symlinks - เนื่องจาก symlink ปรากฏเป็นไฟล์ จึงมักถูกอ่านเป็นไฟล์ ซึ่งอาจนำไปสู่การหาประโยชน์ได้ ตัวอย่างเช่น องค์ประกอบที่มีสิทธิพิเศษบางอย่าง เช่น init เปลี่ยนการอนุญาตของไฟล์บางไฟล์ บางครั้งเปิดมากเกินไป

จากนั้นผู้โจมตีอาจแทนที่ไฟล์เหล่านั้นด้วยลิงก์เชื่อมโยงไปยังโค้ดที่พวกเขาควบคุม ทำให้ผู้โจมตีสามารถเขียนทับไฟล์โดยพลการได้ แต่ถ้าคุณรู้ว่าแอปพลิเคชันของคุณจะไม่มีวันข้าม symlink คุณสามารถห้ามไม่ให้ทำเช่นนั้นด้วย SELinux

ไฟล์ระบบ - พิจารณาคลาสของไฟล์ระบบที่ควรแก้ไขโดยเซิร์ฟเวอร์ระบบเท่านั้น อย่างไรก็ตาม เนื่องจาก netd , init และ vold ทำงานเป็นรูท พวกเขาจึงสามารถเข้าถึงไฟล์ระบบเหล่านั้นได้ ดังนั้นหาก netd ถูกบุกรุกก็อาจทำให้ไฟล์เหล่านั้นประนีประนอมและอาจเป็นเซิร์ฟเวอร์ระบบเอง

ด้วย SELinux คุณสามารถระบุไฟล์เหล่านั้นเป็นไฟล์ข้อมูลเซิร์ฟเวอร์ระบบได้ ดังนั้น โดเมนเดียวที่มีสิทธิ์เข้าถึงแบบอ่าน/เขียนคือเซิร์ฟเวอร์ระบบ แม้ว่า netd ถูกบุกรุก แต่ก็ไม่สามารถเปลี่ยนโดเมนเป็นโดเมนเซิร์ฟเวอร์ระบบและเข้าถึงไฟล์ระบบเหล่านั้นได้แม้ว่าจะทำงานเป็นรูทก็ตาม

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

setattr - สำหรับคำสั่งเช่น chmod และ chown คุณสามารถระบุชุดของไฟล์ที่โดเมนที่เกี่ยวข้องสามารถดำเนินการ setattr สิ่งใดนอกเหนือจากนั้นอาจถูกห้ามไม่ให้ทำการเปลี่ยนแปลงเหล่านี้ แม้จะทำการรูทก็ตาม ดังนั้นแอปพลิเคชันอาจเรียกใช้ chmod และเทียบกับ app_data_files ที่มีป้ายกำกับ แต่ shell_data_files chown system_data_files