กระบวนการ init มีสิทธิ์ที่แทบจะไม่มีข้อจำกัดและใช้สคริปต์อินพุตจากทั้งพาร์ติชันระบบและพาร์ติชันของผู้ให้บริการเพื่อเริ่มต้นระบบในระหว่างกระบวนการบูต การเข้าถึงนี้ทำให้เกิดช่องโหว่ขนาดใหญ่ในการแยกส่วนระบบ/ผู้ให้บริการของ Treble เนื่องจาก สคริปต์ของผู้ให้บริการอาจสั่งให้ init เข้าถึงไฟล์ พร็อพเพอร์ตี้ ฯลฯ ที่ไม่ได้ เป็นส่วนหนึ่งของ Application Binary Interface (ABI) ของระบบ-ผู้ให้บริการที่เสถียร
Vendor init ออกแบบมาเพื่อปิดช่องโหว่นี้โดยใช้โดเมน Security-Enhanced Linux (SELinux) vendor_init
แยกต่างหากเพื่อเรียกใช้คำสั่งที่พบใน /vendor
โดยมีสิทธิ์เฉพาะของผู้ให้บริการ
กลไก
Vendor init จะแยกกระบวนการย่อยของ init ในช่วงต้นของกระบวนการบูตด้วยบริบท SELinux u:r:vendor_init:s0
บริบท SELinux นี้มีสิทธิ์น้อยกว่าบริบท init เริ่มต้นอย่างมาก และการเข้าถึงจะจำกัดเฉพาะไฟล์ พร็อพเพอร์ตี้ ฯลฯ ที่เป็นของผู้ให้บริการโดยเฉพาะหรือเป็นส่วนหนึ่งของ ABI ของผู้ให้บริการระบบที่เสถียร
Init จะตรวจสอบสคริปต์แต่ละรายการที่โหลดเพื่อดูว่าเส้นทางขึ้นต้นด้วย
/vendor
หรือไม่ หากใช่ ระบบจะติดแท็กพร้อมข้อบ่งชี้ว่าต้องเรียกใช้คำสั่งในบริบท Init ของผู้ให้บริการ แต่ละ init builtin จะมีคำอธิบายประกอบด้วยบูลีนที่ระบุว่าต้องเรียกใช้คำสั่งในกระบวนการย่อยของ init ของผู้ให้บริการหรือไม่
- คำสั่งส่วนใหญ่ที่เข้าถึงระบบไฟล์จะมีคำอธิบายประกอบเพื่อให้ทำงานในกระบวนการย่อยของ init ของผู้จำหน่าย จึงขึ้นอยู่กับ SEPolicy ของ init ของผู้จำหน่าย
- คำสั่งส่วนใหญ่ที่มีผลต่อสถานะเริ่มต้นภายใน (เช่น การเริ่มและหยุด บริการ) จะทำงานภายในกระบวนการเริ่มต้นปกติ คำสั่งเหล่านี้จะรับรู้ว่าสคริปต์ของผู้ให้บริการเรียกใช้คำสั่งเพื่อจัดการสิทธิ์ที่ไม่ใช่ SELinux ของตนเอง
ลูปการประมวลผลหลักของ init มีการตรวจสอบว่าหากมีการใส่คำอธิบายประกอบคำสั่ง ให้เรียกใช้ในกระบวนการย่อยของผู้ให้บริการและมาจากสคริปต์ของผู้ให้บริการ ระบบจะส่งคำสั่งนั้นผ่านการสื่อสารระหว่างกระบวนการ (IPC) ไปยังกระบวนการย่อย init ของผู้ให้บริการ ซึ่งจะเรียกใช้คำสั่งและส่งผลลัพธ์กลับไปยัง init
ใช้ vendor init
Vendor Init จะเปิดใช้โดยค่าเริ่มต้นและข้อจำกัดจะมีผลกับสคริปต์ Init ทั้งหมด
ที่อยู่ในพาร์ติชัน /vendor
Vendor init ควรมีความโปร่งใส
ต่อผู้ให้บริการที่มีสคริปต์ซึ่งไม่ได้เข้าถึงไฟล์ของระบบเท่านั้น
พร็อพเพอร์ตี้ ฯลฯ อยู่แล้ว
อย่างไรก็ตาม หากคำสั่งในสคริปต์ของผู้ให้บริการละเมิดข้อจำกัดของ vendor init คำสั่งจะทำงานไม่สำเร็จ คำสั่งที่ไม่สำเร็จจะมีบรรทัดในเคอร์เนล บันทึก (ดูได้ด้วย 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
หากคำสั่งไม่สำเร็จ คุณมี 2 ตัวเลือกดังนี้
- หากคำสั่งล้มเหลวเนื่องจากข้อจำกัดที่ตั้งใจไว้ (เช่น หากคำสั่งเข้าถึงไฟล์หรือพร็อพเพอร์ตี้ของระบบ) จะต้องนำคำสั่งไปใช้ใหม่ในลักษณะที่ Treble รองรับ โดยใช้เฉพาะอินเทอร์เฟซที่เสถียร กฎ Neverallow จะป้องกันการเพิ่มสิทธิ์ในการเข้าถึงไฟล์ระบบที่ไม่ได้ เป็นส่วนหนึ่งของ ABI ของผู้ให้บริการระบบที่เสถียร
- หากป้ายกำกับ SELinux เป็นป้ายกำกับใหม่และยังไม่ได้รับสิทธิ์ใน
vendor_init.te
ระบบ หรือสิทธิ์ที่ยกเว้นผ่านกฎ neverallow ป้ายกำกับใหม่นี้อาจได้รับสิทธิ์ในvendor_init.te
ที่เฉพาะเจาะจงกับอุปกรณ์
สำหรับอุปกรณ์ที่เปิดตัวก่อน Android 9 คุณอาจข้ามกฎ neverallows ได้โดย
เพิ่ม data_between_core_and_vendor_violators
typeattribute ไปยัง
ไฟล์ vendor_init.te
เฉพาะอุปกรณ์
ตำแหน่งของโค้ด
ตรรกะส่วนใหญ่สำหรับ IPC ของการเริ่มต้นของผู้ให้บริการจะอยู่ใน system/core/init/subcontext.cpp
ตารางคำสั่งอยู่ในคลาส BuiltinFunctionMap
ใน system/core/init/builtins.cpp
และมีคำอธิบายประกอบที่ระบุว่าคำสั่งต้องทำงานในกระบวนการย่อย vendor
init หรือไม่
SEPolicy สำหรับ vendor init จะแยกอยู่ในไดเรกทอรีส่วนตัว (system/sepolicy/private/vendor_init.te) และสาธารณะ (system/sepolicy/public/vendor_init.te) ใน system/sepolicy