เพื่อปรับปรุงความปลอดภัยของอุปกรณ์ Android 7.0 ได้แบ่งกระบวนการ mediaserver
ขนาดใหญ่ออกเป็นหลายกระบวนการ โดยมีสิทธิ์และความสามารถจำกัดเฉพาะกระบวนการที่จำเป็นสำหรับแต่ละกระบวนการเท่านั้น การเปลี่ยนแปลงเหล่านี้ช่วยลดความเสี่ยงด้านความปลอดภัยของกรอบสื่อสื่อโดย:
- การแยกส่วนประกอบไปป์ไลน์ AV ออกเป็นกระบวนการแซนด์บ็อกซ์เฉพาะแอป
- การเปิดใช้งานส่วนประกอบสื่อที่สามารถอัพเดตได้ (ตัวแยกไฟล์ ตัวแปลงสัญญาณ ฯลฯ)
การเปลี่ยนแปลงเหล่านี้ยังปรับปรุงความปลอดภัยสำหรับผู้ใช้ปลายทางด้วยการลดความรุนแรงของช่องโหว่ด้านความปลอดภัยที่เกี่ยวข้องกับสื่อส่วนใหญ่ ทำให้อุปกรณ์และข้อมูลของผู้ใช้ปลายทางปลอดภัย
ผู้จำหน่าย OEM และ SoC จำเป็นต้องอัปเดต HAL และการเปลี่ยนแปลงเฟรมเวิร์กเพื่อให้เข้ากันได้กับสถาปัตยกรรมใหม่ โดยเฉพาะอย่างยิ่ง เนื่องจากโค้ด Android ของผู้จำหน่ายมักจะถือว่าทุกอย่างทำงานอยู่ในกระบวนการเดียวกัน ผู้จำหน่ายจึงต้องอัปเดตโค้ดของตนเพื่อส่งต่อไปยังเนทิฟแฮนเดิล ( native_handle
) ที่มีความหมายข้ามกระบวนการ สำหรับการดำเนินการอ้างอิงของการเปลี่ยนแปลงที่เกี่ยวข้องกับการทำให้สื่อแข็งขึ้น โปรดดูที่ frameworks/av
และ frameworks/native
การเปลี่ยนแปลงทางสถาปัตยกรรม
Android เวอร์ชันก่อนหน้าใช้กระบวนการ mediaserver
ขนาดใหญ่ก้อนเดียวพร้อมสิทธิ์มากมาย (การเข้าถึงกล้อง การเข้าถึงเสียง การเข้าถึงไดรเวอร์วิดีโอ การเข้าถึงไฟล์ การเข้าถึงเครือข่าย ฯลฯ) Android 7.0 แบ่งกระบวนการ mediaserver
ออกเป็นกระบวนการใหม่หลายกระบวนการ ซึ่งแต่ละกระบวนการต้องการชุดสิทธิ์ที่น้อยกว่ามาก:
สถาปัตยกรรมใหม่นี้ช่วยให้แน่ใจว่าแม้ว่ากระบวนการจะถูกบุกรุก โค้ดที่เป็นอันตรายจะไม่สามารถเข้าถึงชุดสิทธิ์ทั้งหมดก่อนหน้านี้ที่ mediaserver
เก็บไว้ กระบวนการถูกจำกัดโดยนโยบาย 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 หรือ MPEG4Extractor) และส่งคืนอินเทอร์เฟซ Binder สำหรับตัวแยกไปยังกระบวนการของ
mediaserver
- ทำการเรียก Binder IPC ไปยังตัวแยกเพื่อกำหนดประเภทของข้อมูลในไฟล์ (เช่น ข้อมูล MP3 หรือ H.264)
- เรียกเข้าสู่กระบวนการ
mediacodec
เพื่อสร้างตัวแปลงสัญญาณประเภทที่ต้องการ รับอินเทอร์เฟซ Binder สำหรับตัวแปลงสัญญาณเหล่านี้ - ทำการเรียก Binder IPC ซ้ำไปยังตัวแยกเพื่ออ่านตัวอย่างที่เข้ารหัส ใช้ Binder IPC เพื่อส่งข้อมูลที่เข้ารหัสไปยังกระบวนการ
mediacodec
สำหรับการถอดรหัส และรับข้อมูลที่ถอดรหัส
ในบางกรณีการใช้งาน ไม่มีตัวแปลงสัญญาณเข้ามาเกี่ยวข้อง (เช่น การเล่นแบบออฟโหลดซึ่งข้อมูลที่เข้ารหัสจะถูกส่งไปยังอุปกรณ์เอาท์พุตโดยตรง) หรือตัวแปลงสัญญาณอาจแสดงผลข้อมูลที่ถอดรหัสโดยตรงแทนที่จะส่งคืนบัฟเฟอร์ของข้อมูลที่ถอดรหัส (การเล่นวิดีโอ)
การเปลี่ยนแปลง MediaCodecService
บริการตัวแปลงสัญญาณเป็นที่ที่ตัวเข้ารหัสและตัวถอดรหัสอาศัยอยู่ เนื่องจากการพึ่งพาของผู้ขาย ตัวแปลงสัญญาณบางตัวอาจไม่อยู่ในกระบวนการตัวแปลงสัญญาณ ใน Android 7.0:
- ตัวถอดรหัสที่ไม่ปลอดภัยและตัวเข้ารหัสซอฟต์แวร์อยู่ในกระบวนการตัวแปลงสัญญาณ
- ตัวถอดรหัสที่ปลอดภัยและตัวเข้ารหัสฮาร์ดแวร์อยู่ใน
mediaserver
(ไม่เปลี่ยนแปลง)
แอป (หรือ mediaserver
) เรียกกระบวนการตัวแปลงสัญญาณเพื่อสร้างตัวแปลงสัญญาณประเภทที่ต้องการ จากนั้นเรียกตัวแปลงสัญญาณนั้นให้ส่งผ่านข้อมูลที่เข้ารหัสและดึงข้อมูลที่ถอดรหัส (สำหรับการถอดรหัส) หรือส่งผ่านข้อมูลที่ถอดรหัสและดึงข้อมูลที่เข้ารหัส (สำหรับการเข้ารหัส) . การถ่ายโอนข้อมูลไปและกลับจากตัวแปลงสัญญาณใช้หน่วยความจำที่ใช้ร่วมกันอยู่แล้ว ดังนั้นกระบวนการนั้นจึงไม่เปลี่ยนแปลง
การเปลี่ยนแปลง MediaDrmServer
เซิร์ฟเวอร์ DRM ถูกใช้เมื่อเล่นเนื้อหาที่มีการป้องกัน DRM เช่น ภาพยนตร์ใน Google Play ภาพยนตร์ จัดการการถอดรหัสข้อมูลที่เข้ารหัสในวิธีที่ปลอดภัย และด้วยเหตุนี้จึงสามารถเข้าถึงใบรับรองและที่เก็บข้อมูลคีย์และส่วนประกอบที่ละเอียดอ่อนอื่น ๆ เนื่องจากการพึ่งพาผู้ขาย กระบวนการ DRM จึงยังไม่ได้ใช้ในทุกกรณี
การเปลี่ยนแปลงเซิร์ฟเวอร์เสียง
กระบวนการ AudioServer โฮสต์ส่วนประกอบที่เกี่ยวข้องกับเสียง เช่น อินพุตและเอาต์พุตเสียง บริการตัวจัดการนโยบายที่กำหนดเส้นทางเสียง และบริการวิทยุ FM สำหรับรายละเอียดเกี่ยวกับการเปลี่ยนแปลงเสียงและคำแนะนำการใช้งาน โปรดดูที่ การใช้งานเสียง
การเปลี่ยนแปลงเซิร์ฟเวอร์กล้อง
CameraServer ควบคุมกล้องและใช้เมื่อบันทึกวิดีโอเพื่อรับเฟรมวิดีโอจากกล้องแล้วส่งต่อไปยัง mediaserver
เพื่อการจัดการเพิ่มเติม สำหรับรายละเอียดเกี่ยวกับการเปลี่ยนแปลงและคำแนะนำการใช้งานสำหรับการเปลี่ยนแปลง CameraServer โปรดดูที่ Camera Framework Hardening
การเปลี่ยนแปลง ExtractorService
บริการแยกไฟล์จะโฮสต์ ตัวแยกข้อมูล ซึ่งเป็นส่วนประกอบที่แยกวิเคราะห์รูปแบบไฟล์ต่างๆ ที่กรอบงานสื่อรองรับ บริการแยกไฟล์เป็นสิทธิ์ขั้นต่ำสุดในบรรดาบริการทั้งหมด เนื่องจากไม่สามารถอ่าน FD ได้ ดังนั้นจึงทำการเรียกไปยังอินเทอร์เฟซ Binder แทน (จัดทำโดย mediaserver for
เซสชันการเล่นแต่ละครั้ง) เพื่อเข้าถึงไฟล์
แอพ (หรือ mediaserver
) ทำการเรียกไปยังกระบวนการแยกข้อมูลเพื่อรับ IMediaExtractor
เรียกให้ IMediaExtractor
รับ IMediaSources
สำหรับแทร็กที่มีอยู่ในไฟล์ จากนั้นเรียก IMediaSources
เพื่ออ่านข้อมูลจากพวกเขา
ในการถ่ายโอนข้อมูลระหว่างกระบวนการ แอป (หรือ mediaserver
) จะรวมข้อมูลไว้ในพัสดุตอบกลับโดยเป็นส่วนหนึ่งของธุรกรรม Binder หรือใช้หน่วยความจำที่ใช้ร่วมกัน:
- การใช้ หน่วยความจำแบบแบ่ง ใช้จำเป็นต้องมีการเรียก Binder เพิ่มเติมเพื่อปล่อยหน่วยความจำแบบแบ่งใช้ แต่จะเร็วกว่าและใช้พลังงานน้อยกว่าสำหรับบัฟเฟอร์ขนาดใหญ่
- การใช้ ในพัสดุ ต้องมีการคัดลอกเพิ่มเติมแต่เร็วกว่าและใช้พลังงานน้อยกว่าสำหรับบัฟเฟอร์ที่มีขนาดเล็กกว่า 64KB
การนำไปปฏิบัติ
เพื่อรองรับการย้ายส่วนประกอบ MediaDrm
และ MediaCrypto
เข้าสู่กระบวนการ mediadrmserver
ใหม่ ผู้จำหน่ายจะต้องเปลี่ยนวิธีการจัดสรรสำหรับบัฟเฟอร์ที่ปลอดภัย เพื่อให้สามารถใช้บัฟเฟอร์ร่วมกันระหว่างกระบวนการได้
ใน Android รุ่นก่อนหน้านี้ บัฟเฟอร์ที่ปลอดภัยจะได้รับการจัดสรรใน mediaserver
โดย OMX::allocateBuffer
และใช้ในระหว่างการถอดรหัสในกระบวนการเดียวกัน ดังที่แสดงด้านล่าง:
ใน Android 7.0 กระบวนการจัดสรรบัฟเฟอร์ได้เปลี่ยนไปเป็นกลไกใหม่ที่ให้ความยืดหยุ่นในขณะที่ลดผลกระทบต่อการใช้งานที่มีอยู่ให้เหลือน้อยที่สุด ด้วย MediaDrm
และ MediaCrypto
stacks ในกระบวนการ mediadrmserver
ใหม่ บัฟเฟอร์จะถูกจัดสรรแตกต่างกัน และผู้ขายต้องอัปเดตตัวจัดการบัฟเฟอร์ที่ปลอดภัย เพื่อให้สามารถขนส่งข้าม Binder ได้เมื่อ MediaCodec
เรียกใช้การดำเนินการถอดรหัสบน MediaCrypto
ใช้แฮนเดิลดั้งเดิม
OMX::allocateBuffer
ต้องส่งคืนตัวชี้ไปยังโครงสร้าง native_handle
ซึ่งมีตัวอธิบายไฟล์ (FD) และข้อมูลจำนวนเต็มเพิ่มเติม native_handle
มีข้อดีทั้งหมดของการใช้ FD รวมถึงการรองรับ Binder ที่มีอยู่สำหรับการซีเรียลไลซ์/การดีซีเรียลไลซ์ ขณะเดียวกันก็ให้ความยืดหยุ่นมากขึ้นสำหรับผู้จำหน่ายที่ไม่ได้ใช้ 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 ซึ่งควรใช้ตัวจัดการดั้งเดิม