Init ของผู้ให้บริการ

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

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

กลไก

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

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

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

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

การใช้ Init ของผู้ให้บริการ

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

อย่างไรก็ตาม หากคำสั่งในสคริปต์ของผู้ให้บริการที่ระบุละเมิดคำสั่งของผู้ให้บริการ จะทำให้ไม่สามารถใช้คำสั่งได้ คำสั่งที่ล้มเหลวจะมีบรรทัดอยู่ในเคอร์เนล log (แสดงโดยมี 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 หรือสิทธิ์ที่ยกเว้นผ่านรายการที่อนุญาต คุณอาจได้รับสิทธิ์ในป้ายกำกับใหม่ในอุปกรณ์ vendor_init.te

สำหรับอุปกรณ์ที่เปิดตัวก่อน Android 9 ระบบอาจข้ามกฎ "Neverallows" กำลังเพิ่มแอตทริบิวต์ประเภท data_between_core_and_vendor_violators ลงใน ไฟล์ vendor_init.te เฉพาะอุปกรณ์

ตำแหน่งรหัส

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

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

SEPolicy สำหรับ Init ของผู้ให้บริการแยกออกเป็น Private (system/sepolicy/private/vendor_init.te) และสาธารณะ (system/sepolicy/public/vendor_init.te) ไดเรกทอรีในระบบ/sepolicy