ใช้งาน SELinux

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

ไฟล์คีย์

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

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

ไฟล์นโยบาย

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

ไฟล์บริบท

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

  • file_contexts กำหนดป้ายกำกับให้กับไฟล์และคอมโพเนนต์ต่างๆ ของพื้นที่ผู้ใช้ใช้ เมื่อคุณสร้างนโยบายใหม่ ให้สร้างหรืออัปเดตไฟล์นี้ เพื่อกำหนดป้ายกำกับใหม่ให้กับไฟล์ หากต้องการใช้file_contextsใหม่ สร้างอิมเมจระบบไฟล์อีกครั้งหรือเรียกใช้ restorecon บนไฟล์เพื่อ ติดป้ายกำกับใหม่ ในการอัปเกรด การเปลี่ยนแปลงใน file_contexts จะมีผลกับพาร์ติชันระบบและพาร์ติชันข้อมูลผู้ใช้โดยอัตโนมัติโดยเป็นส่วนหนึ่งของการอัปเกรด การเปลี่ยนแปลงจะมีผลโดยอัตโนมัติเมื่ออัปเกรดเป็น พาร์ติชันโดยเพิ่มการเรียก restorecon_recursive ไปยัง init.board.rc หลังจากต่อเชื่อมพาร์ติชันแล้ว Read-Write
  • genfs_contexts กำหนดป้ายกำกับให้กับระบบไฟล์ เช่น proc หรือ vfat ที่ไม่รองรับแอตทริบิวต์แบบขยาย ระบบจะโหลดการกําหนดค่านี้เป็นส่วนหนึ่งของนโยบายเคอร์เนล แต่การเปลี่ยนแปลงอาจไม่มีผลกับอินโนดในเคอร์เนล ซึ่งจะต้องรีบูตหรือยกเลิกการต่อเชื่อมและต่อเชื่อมระบบไฟล์อีกครั้งเพื่อให้การเปลี่ยนแปลงมีผลอย่างสมบูรณ์ นอกจากนี้ คุณยังกำหนดป้ายกำกับเฉพาะให้กับการต่อเชื่อมที่เฉพาะเจาะจงได้ด้วย เช่น 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 มีคีย์สโตร์อยู่เสมอ เนมสเปซที่อิงตาม UID/AID ที่ระบุ นอกจากนี้ Keystore 2.0 ยังบังคับใช้เนมสเปซที่กําหนดโดย sepolicy ด้วย ดูคำอธิบายโดยละเอียดเกี่ยวกับรูปแบบและรูปแบบของไฟล์นี้ได้ที่นี่

ไฟล์ทำ BoardConfig.mk

หลังจากแก้ไขหรือเพิ่มไฟล์นโยบายและบริบทแล้ว ให้อัปเดตไฟล์ /device/manufacturer/device-name/BoardConfig.mkmakefile เพื่ออ้างอิงไดเรกทอรีย่อย 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 ตามที่อธิบายไว้ใน การปรับแต่ง หรือยืนยัน การตั้งค่าที่มีอยู่ตามที่ระบุไว้ใน การตรวจสอบความถูกต้อง

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

การใช้งาน

วิธีเริ่มต้นใช้งาน SELinux

  1. เปิดใช้ SELinux ในเคอร์เนล โดยทำดังนี้ CONFIG_SECURITY_SELINUX=y
  2. เปลี่ยนพารามิเตอร์ kernel_cmdline หรือ Bootconfig เพื่อที่ว่า
    BOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
    หรือ
    BOARD_BOOTCONFIG := androidboot.selinux=permissive
    นโยบายนี้ใช้สำหรับการพัฒนานโยบายเบื้องต้นสำหรับอุปกรณ์เท่านั้น หลังจากที่คุณ มีนโยบาย Bootstrap เริ่มต้น ลบพารามิเตอร์นี้เพื่อให้ อุปกรณ์บังคับใช้หรือไม่ทำตาม 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. ตรวจสอบไฟล์ init.device.rc และ fstab.device และตรวจสอบว่าการใช้ mount ทั้งหมดสอดคล้องกับระบบไฟล์ที่ติดป้ายกำกับอย่างถูกต้อง หรือมีการระบุตัวเลือก context= mount
  11. ตรวจสอบการปฏิเสธแต่ละรายการและสร้างนโยบาย SELinux เพื่อจัดการแต่ละรายการอย่างเหมาะสม ดูตัวอย่างในการปรับแต่ง

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

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

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

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

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

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

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

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

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