ผู้ขายเริ่มต้น

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

Vendor init ได้รับการออกแบบมาเพื่อปิดช่องโหว่นี้โดยใช้โดเมน vendor_init ที่เสริมความปลอดภัยด้วย Linux (SELinux) แยกต่างหาก เพื่อรันคำสั่งที่พบใน /vendor ด้วยสิทธิ์เฉพาะของผู้จำหน่าย

กลไก

ผู้ขาย init แยกกระบวนการย่อยของ init ในช่วงต้นของกระบวนการบูตด้วยบริบท SELinux u:r:vendor_init:s0 บริบท SELinux นี้มีสิทธิ์น้อยกว่าบริบทเริ่มต้นเริ่มต้นอย่างมาก และการเข้าถึงนั้นจำกัดอยู่ที่ไฟล์ คุณสมบัติ และอื่นๆ ที่เป็นเฉพาะผู้จำหน่ายหรือเป็นส่วนหนึ่งของ ABI ผู้จำหน่ายระบบที่เสถียร

Init ตรวจสอบแต่ละสคริปต์ที่โหลดเพื่อดูว่าเส้นทางเริ่มต้นด้วย /vendor หรือไม่ และหากเป็นเช่นนั้น ให้แท็กสคริปต์ด้วยการบ่งชี้ว่าคำสั่งจะต้องทำงานในบริบทเริ่มต้นของผู้ขาย บิวอิน init แต่ละอันมีคำอธิบายประกอบด้วยบูลีนที่ระบุว่าจะต้องรันคำสั่งในกระบวนการย่อย init ของผู้จำหน่ายหรือไม่:

  • คำสั่งส่วนใหญ่ที่เข้าถึงระบบไฟล์จะมีคำอธิบายประกอบให้รันในกระบวนการย่อย init ของผู้จำหน่าย และดังนั้นจึงอยู่ภายใต้ SEPolicy ของ init ของผู้จำหน่าย
  • คำสั่งส่วนใหญ่ที่ส่งผลกระทบต่อสถานะเริ่มต้นภายใน (เช่น การเริ่มและการหยุดบริการ) จะถูกรันภายในกระบวนการเริ่มต้นปกติ คำสั่งเหล่านี้ได้รับทราบว่าสคริปต์ผู้ขายกำลังเรียกให้ดำเนินการจัดการสิทธิ์ที่ไม่ใช่ SELinux ของตนเอง

ลูปการประมวลผลหลักของ init มีการตรวจสอบว่าหากคำสั่งถูกใส่คำอธิบายประกอบให้รันในกระบวนการย่อยของผู้จำหน่ายและมีต้นกำเนิดจากสคริปต์ของผู้จำหน่าย คำสั่งนั้นจะถูกส่งผ่านการสื่อสารระหว่างกระบวนการ (IPC) ไปยังกระบวนการย่อย init ของผู้จำหน่าย ซึ่งรันคำสั่ง และส่งผลลัพธ์กลับไปที่ init

การใช้ผู้ขาย Init

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

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

type=1400 audit(1511821362.996:9): avc: denied { search } for pid=540 comm="init" name="nfc" dev="sda45" ino=1310721 scontext=u:r:vendor_init:s0 tcontext=u:object_r:nfc_data_file:s0 tclass=dir permissive=0
init: Command 'write /data/nfc/bad_file_access 1234' action=boot (/vendor/etc/init/hw/init.walleye.rc:422) took 2ms and failed: Unable to write to file '/data/nfc/bad_file_access': open() failed: Permission denied

หากคำสั่งล้มเหลว มีสองตัวเลือก:

  • หากคำสั่งล้มเหลวเนื่องจากข้อจำกัดที่ตั้งใจไว้ (เช่น หากคำสั่งกำลังเข้าถึงไฟล์ระบบหรือคุณสมบัติ) คำสั่งจะต้องถูกนำไปใช้ใหม่ในลักษณะที่เป็นมิตรต่อเสียงแหลม โดยดำเนินการผ่านอินเทอร์เฟซที่เสถียรเท่านั้น กฎ Neverallow ป้องกันการเพิ่มสิทธิ์ในการเข้าถึงไฟล์ระบบที่ไม่ได้เป็นส่วนหนึ่งของ ABI ของผู้จำหน่ายระบบที่เสถียร
  • หากป้ายกำกับ SELinux เป็นป้ายกำกับใหม่และยังไม่ได้รับสิทธิ์ในระบบ vendor_init.te หรือการอนุญาตที่ยกเว้นผ่านกฎ neverallow ป้ายกำกับใหม่อาจได้รับสิทธิ์ใน vendor_init.te เฉพาะอุปกรณ์

สำหรับอุปกรณ์ที่เปิดตัวก่อน Android 9 กฎ neverallow อาจถูกข้ามโดยการเพิ่ม data_between_core_and_vendor_violators typeattribute ให้กับไฟล์ vendor_init.te เฉพาะอุปกรณ์

ที่ตั้งรหัส

ตรรกะส่วนใหญ่สำหรับผู้ขาย init IPC อยู่ใน system/core/init/subcontext.cpp

ตารางคำสั่งอยู่ในคลาส BuiltinFunctionMap ใน system/core/init/builtins.cpp และมีคำอธิบายประกอบที่ระบุว่าคำสั่งต้องรันในกระบวนการย่อย init ของผู้จำหน่ายหรือไม่

SEPolicy สำหรับ vendor init ถูกแบ่งระหว่างไดเร็กทอรีไพรเวต ( system/sepolicy/private/vendor_init.te ) และไดเร็กทอรีสาธารณะ ( system/sepolicy/public/vendor_init.te ) ในระบบ/sepolicy