ผู้ให้บริการเริ่มต้น

กระบวนการ 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