เพื่อปรับปรุงความปลอดภัยของอุปกรณ์ Android 7.0 ได้แบ่งกระบวนการ mediaserver
สื่อแบบเสาหินออกเป็นหลายกระบวนการโดยมีการอนุญาตและความสามารถที่จำกัดไว้เฉพาะที่จำเป็นในแต่ละกระบวนการเท่านั้น การเปลี่ยนแปลงเหล่านี้ช่วยบรรเทาช่องโหว่ด้านความปลอดภัยของกรอบงานสื่อโดย:
- แยกส่วนประกอบไปป์ไลน์ AV ออกเป็นกระบวนการแซนด์บ็อกซ์เฉพาะแอป
- การเปิดใช้งานคอมโพเนนต์สื่อที่อัพเดตได้ (ตัวแยก ตัวแปลงสัญญาณ ฯลฯ)
การเปลี่ยนแปลงเหล่านี้ยังช่วยปรับปรุงการรักษาความปลอดภัยสำหรับผู้ใช้ด้วยการลดความรุนแรงของช่องโหว่ด้านความปลอดภัยที่เกี่ยวข้องกับสื่อส่วนใหญ่อย่างมาก ทำให้อุปกรณ์ของผู้ใช้ปลายทางและข้อมูลมีความปลอดภัย
OEM และผู้จำหน่าย SoC จำเป็นต้องอัปเดต HAL และการเปลี่ยนแปลงกรอบงานเพื่อให้เข้ากันได้กับสถาปัตยกรรมใหม่ โดยเฉพาะอย่างยิ่ง เนื่องจากโค้ด Android ที่ผู้ขายจัดหาให้มักจะถือว่าทุกอย่างทำงานในกระบวนการเดียวกัน ผู้ขายต้องอัปเดตโค้ดของตนเพื่อส่งต่อแฮนเดิลดั้งเดิม ( native_handle
) ที่มีความหมายข้ามกระบวนการ สำหรับการใช้งานอ้างอิงของการเปลี่ยนแปลงที่เกี่ยวข้องกับการชุบแข็งของสื่อ โปรดดู frameworks/av
และ frameworks/native
การเปลี่ยนแปลงทางสถาปัตยกรรม
Android เวอร์ชันก่อนหน้าใช้กระบวนการ mediaserver
แบบเสาหินเดียวที่มีการอนุญาตมากมาย (การเข้าถึงกล้อง การเข้าถึงเสียง การเข้าถึงไดรเวอร์วิดีโอ การเข้าถึงไฟล์ การเข้าถึงเครือข่าย ฯลฯ) Android 7.0 แบ่งกระบวนการ mediaserver
ออกเป็นกระบวนการใหม่หลายขั้นตอน ซึ่งแต่ละกระบวนการต้องการชุดการอนุญาตที่น้อยกว่ามาก:
รูปที่ 1 การเปลี่ยนแปลงสถาปัตยกรรมสำหรับการชุบแข็งเซิร์ฟเวอร์สื่อ
สถาปัตยกรรมใหม่นี้ช่วยให้มั่นใจได้ว่าแม้ว่ากระบวนการจะถูกบุกรุก แต่โค้ดที่เป็นอันตรายจะไม่สามารถเข้าถึงชุดสิทธิ์ทั้งหมดที่จัดขึ้นโดยเซิร์ฟเวอร์มีเดียก่อนหน้านี้ กระบวนการถูกจำกัดโดยนโยบาย SElinux และ seccomp
หมายเหตุ: เนื่องจากการขึ้นต่อกันของผู้ขาย ตัวแปลงสัญญาณบางตัวยังคงทำงานใน mediaserver
และทำให้ mediaserver
ได้รับสิทธิ์มากกว่าที่จำเป็น โดยเฉพาะ Widevine Classic ยังคงทำงานใน mediaserver
สำหรับ Android 7.0
MediaServer เปลี่ยนแปลง
ใน Android 7.0 มีกระบวนการ mediaserver
สำหรับการขับเคลื่อนการเล่นและการบันทึก เช่น การส่งและการซิงโครไนซ์บัฟเฟอร์ระหว่างส่วนประกอบและกระบวนการ กระบวนการสื่อสารผ่านกลไก Binder มาตรฐาน
ในเซสชันการเล่นไฟล์ในเครื่องมาตรฐาน แอปพลิเคชันจะส่ง file descriptor (FD) ไปยัง mediaserver
(โดยปกติผ่านทาง MediaPlayer Java API) และ mediaserver
:
- รวม FD ลงในวัตถุ Binder DataSource ที่ส่งผ่านไปยังกระบวนการแยก ซึ่งใช้เพื่ออ่านจากไฟล์โดยใช้ Binder IPC (ตัวแยกสื่อไม่ได้รับ FD แต่ให้ Binder โทรกลับไปที่
mediaserver
สื่อเพื่อรับข้อมูล) - ตรวจสอบไฟล์ สร้างตัวแยกที่เหมาะสมสำหรับประเภทไฟล์ (เช่น MP3Extractor หรือ
mediaserver
) และส่งคืนอินเทอร์เฟซ Binder สำหรับตัวแยกไปยังกระบวนการเซิร์ฟเวอร์สื่อ - ทำการเรียก Binder IPC ไปยังตัวแยกเพื่อกำหนดประเภทของข้อมูลในไฟล์ (เช่น ข้อมูล MP3 หรือ H.264)
- เรียกเข้าสู่กระบวนการ
mediacodec
เพื่อสร้างตัวแปลงสัญญาณประเภทที่ต้องการ ได้รับอินเทอร์เฟซ Binder สำหรับตัวแปลงสัญญาณเหล่านี้ - เรียกใช้ Binder IPC ซ้ำๆ ไปยังตัวแยกเพื่ออ่านตัวอย่างที่เข้ารหัส ใช้ Binder IPC เพื่อส่งข้อมูลที่เข้ารหัสไปยังกระบวนการ
mediacodec
เพื่อถอดรหัส และรับข้อมูลที่ถอดรหัสแล้ว
ในบางกรณีการใช้งาน ไม่มีตัวแปลงสัญญาณที่เกี่ยวข้อง (เช่น การเล่นออฟโหลดโดยที่ข้อมูลที่เข้ารหัสจะถูกส่งไปยังอุปกรณ์ส่งออกโดยตรง) หรือตัวแปลงสัญญาณอาจแสดงข้อมูลที่ถอดรหัสโดยตรงแทนที่จะส่งคืนบัฟเฟอร์ของข้อมูลที่ถอดรหัสแล้ว (การเล่นวิดีโอ)
การเปลี่ยนแปลงบริการ MediaCodec
บริการตัวแปลงสัญญาณเป็นที่ที่ตัวเข้ารหัสและตัวถอดรหัสอยู่ เนื่องจากการขึ้นต่อกันของผู้ขาย ตัวแปลงสัญญาณทั้งหมดยังไม่อยู่ในกระบวนการตัวแปลงสัญญาณ ใน Android 7.0:
- ตัวถอดรหัสและตัวเข้ารหัสซอฟต์แวร์ที่ไม่ปลอดภัยอยู่ในกระบวนการตัวแปลงสัญญาณ
- ตัวถอดรหัสและตัวเข้ารหัสฮาร์ดแวร์ที่ปลอดภัยอยู่ใน
mediaserver
(ไม่เปลี่ยนแปลง)
แอปพลิเคชัน (หรือเซิร์ฟเวอร์มีเดีย) เรียกใช้กระบวนการตัวแปลงสัญญาณเพื่อสร้างตัวแปลงสัญญาณประเภทที่ต้องการ จากนั้นเรียกตัวแปลงสัญญาณนั้นให้ส่งผ่านข้อมูลที่เข้ารหัสและดึงข้อมูลที่ถอดรหัสแล้ว (เพื่อถอดรหัส) หรือส่งผ่านข้อมูลที่ถอดรหัสแล้วดึงข้อมูลที่เข้ารหัส (สำหรับการเข้ารหัส) . การถ่ายโอนข้อมูลเข้าและออกจากตัวแปลงสัญญาณใช้หน่วยความจำที่ใช้ร่วมกันอยู่แล้ว ดังนั้นกระบวนการจึงไม่เปลี่ยนแปลง
MediaDrmServer เปลี่ยนไป
เซิร์ฟเวอร์ DRM จะใช้เมื่อเล่นเนื้อหาที่มีการป้องกันด้วย DRM เช่น ภาพยนตร์ใน Google Play ภาพยนตร์ มันจัดการถอดรหัสข้อมูลที่เข้ารหัสด้วยวิธีที่ปลอดภัย และด้วยเหตุนี้จึงมีการเข้าถึงใบรับรองและที่จัดเก็บคีย์และส่วนประกอบที่สำคัญอื่น ๆ เนื่องจากการขึ้นต่อกันของผู้ขาย กระบวนการ DRM ยังไม่ถูกใช้ในทุกกรณี
การเปลี่ยนแปลงเซิร์ฟเวอร์เสียง
กระบวนการ AudioServer โฮสต์ส่วนประกอบที่เกี่ยวข้องกับเสียง เช่น อินพุตและเอาต์พุตเสียง บริการผู้จัดการนโยบายที่กำหนดเส้นทางเสียง และบริการวิทยุ FM สำหรับรายละเอียดเกี่ยวกับการเปลี่ยนแปลงเสียงและคำแนะนำในการใช้งาน โปรดดูที่ Implementing Audio
การเปลี่ยนแปลงเซิร์ฟเวอร์กล้อง
CameraServer ควบคุมกล้องและใช้เมื่อบันทึกวิดีโอเพื่อรับเฟรมวิดีโอจากกล้องแล้วส่งต่อไปยัง mediaserver
เพื่อการจัดการต่อไป สำหรับรายละเอียดเกี่ยวกับการเปลี่ยนแปลงและแนวทางการใช้งานสำหรับการเปลี่ยนแปลง CameraServer โปรดดูที่ Camera Framework Hardening
การเปลี่ยนแปลงบริการ Extractor
บริการตัวแยกไฟล์โฮสต์ตัว แยก ส่วนประกอบที่แยกวิเคราะห์รูปแบบไฟล์ต่างๆ ที่รองรับโดยกรอบงานสื่อ บริการ Extractor เป็นบริการที่มีสิทธิพิเศษน้อยที่สุด เพราะไม่สามารถอ่าน FD ได้ ดังนั้นจึงโทรไปยังอินเทอร์เฟซ Binder (ที่เซิร์ฟเวอร์มีเดียจัดหาให้ mediaserver for
เซสชันการเล่นแต่ละครั้ง) เพื่อเข้าถึงไฟล์
แอปพลิเคชัน (หรือ mediaserver
สื่อ) เรียกกระบวนการแยกเพื่อขอรับ IMediaExtractor
เรียก IMediaExtractor
เพื่อขอรับ IMediaSources
สำหรับแทร็กที่มีอยู่ในไฟล์ จากนั้นเรียก IMediaSources
เพื่ออ่านข้อมูลจากพวกเขา
ในการถ่ายโอนข้อมูลระหว่างกระบวนการ แอปพลิเคชัน (หรือ mediaserver
) จะรวมข้อมูลในพัสดุตอบกลับโดยเป็นส่วนหนึ่งของธุรกรรม Binder หรือใช้หน่วยความจำที่ใช้ร่วมกัน:
- การ ใช้หน่วยความจำที่แชร์ ต้องใช้การเรียก Binder พิเศษเพื่อปล่อยหน่วยความจำที่แชร์ แต่จะเร็วกว่าและใช้พลังงานน้อยกว่าสำหรับบัฟเฟอร์ขนาดใหญ่
- การใช้ ในพัสดุ ต้องมีการคัดลอกเพิ่มเติม แต่เร็วกว่าและใช้พลังงานน้อยกว่าสำหรับบัฟเฟอร์ที่มีขนาดเล็กกว่า 64KB
การดำเนินการ
เพื่อรองรับการย้ายส่วนประกอบ MediaDrm
และ MediaCrypto
ไปสู่กระบวนการ mediadrmserver
ใหม่ ผู้จำหน่ายต้องเปลี่ยนวิธีการจัดสรรสำหรับบัฟเฟอร์ที่ปลอดภัย เพื่อให้สามารถใช้บัฟเฟอร์ร่วมกันระหว่างกระบวนการได้
ใน Android รุ่นก่อนหน้า บัฟเฟอร์ที่ปลอดภัยจะได้รับการจัดสรรใน mediaserver
โดย OMX::allocateBuffer
และใช้ในระหว่างการถอดรหัสในกระบวนการเดียวกันดังที่แสดงด้านล่าง:
รูปที่ 2 Android 6.0 และการจัดสรรบัฟเฟอร์ที่ต่ำกว่าในเซิร์ฟเวอร์มีเดีย
ใน Android 7.0 กระบวนการจัดสรรบัฟเฟอร์ได้เปลี่ยนไปเป็นกลไกใหม่ที่ให้ความยืดหยุ่นในขณะที่ลดผลกระทบต่อการใช้งานที่มีอยู่ให้น้อยที่สุด ด้วยสแต็ก MediaDrm
และ MediaCrypto
ในกระบวนการ mediadrmserver
ใหม่ บัฟเฟอร์จะถูกจัดสรรแตกต่างกัน และผู้ขายต้องอัปเดตตัวจัดการบัฟเฟอร์ที่ปลอดภัย เพื่อให้สามารถขนส่งข้าม Binder เมื่อ MediaCodec
เรียกใช้การดำเนินการถอดรหัสบน MediaCrypto
รูปที่ 3 Android 7.0 และการจัดสรรบัฟเฟอร์ที่สูงกว่าในเซิร์ฟเวอร์มีเดีย
การใช้เนทีฟแฮนเดิล
OMX::allocateBuffer
ต้องส่งคืนตัวชี้ไปยัง native_handle
ซึ่งประกอบด้วย file descriptors (FDs) และข้อมูลจำนวนเต็มเพิ่มเติม native_handle
มีข้อดีทั้งหมดของการใช้ FD รวมถึงการสนับสนุนตัวผูกที่มีอยู่สำหรับการทำให้เป็นอนุกรม/ดีซีเรียลไลเซชัน ในขณะที่ให้ความยืดหยุ่นมากขึ้นสำหรับผู้ขายที่ไม่ได้ใช้ FD ในปัจจุบัน
ใช้ native_handle_create()
เพื่อจัดสรรหมายเลขอ้างอิงดั้งเดิม โค้ดกรอบงานเป็นเจ้าของโครงสร้าง native_handle
ที่จัดสรรไว้ และมีหน้าที่รับผิดชอบในการปล่อยทรัพยากรทั้งในกระบวนการที่ native_handle
ถูกจัดสรรและอยู่ในกระบวนการที่จะถูกดีซีเรียลไลซ์ เฟรมเวิร์กปล่อยตัวจัดการดั้งเดิมด้วย native_handle_close()
ตามด้วย native_handle_delete()
และทำให้เป็นอนุกรม/ดีซีเรีย native_handle
โดยใช้ Parcel::writeNativeHandle()/readNativeHandle()
ผู้จำหน่าย SoC ที่ใช้ FD เพื่อเป็นตัวแทนของบัฟเฟอร์ที่ปลอดภัยสามารถเติม FD ใน native_handle
ด้วย FD ของตนได้ ผู้ขายที่ไม่ได้ใช้ FD สามารถแสดงบัฟเฟอร์ที่ปลอดภัยได้โดยใช้ฟิลด์เพิ่มเติมใน native_buffer
การตั้งค่าตำแหน่งถอดรหัส
ผู้จำหน่ายต้องอัปเดตวิธีการถอดรหัส OEMCrypto ที่ทำงานบน native_handle
เพื่อดำเนินการใดๆ เฉพาะผู้จำหน่ายที่จำเป็นในการทำให้ native_handle
ใช้งานได้ในพื้นที่กระบวนการใหม่ (โดยทั่วไปการเปลี่ยนแปลงจะรวมถึงการอัปเดตไลบรารี OEMCrypto)
เนื่องจาก allocateBuffer
เป็นการดำเนินการ OMX มาตรฐาน Android 7.0 จึงรวมส่วนขยาย OMX ใหม่ ( OMX.google.android.index.allocateNativeHandle
) เพื่อสอบถามเกี่ยวกับการสนับสนุนนี้และการเรียก OMX_SetParameter
ที่แจ้งการใช้งาน OMX ว่าควรใช้ตัวจัดการแบบเนทีฟ