Android 7.0 ได้แยกกระบวนการแบบโมโนลิธิกmediaserver
ออกเป็นหลายกระบวนการที่มีสิทธิ์และความสามารถที่จำกัดไว้เฉพาะที่แต่ละกระบวนการต้องใช้ เพื่อปรับปรุงความปลอดภัยของอุปกรณ์ การเปลี่ยนแปลงเหล่านี้จะช่วยลดช่องโหว่ด้านความปลอดภัยของเฟรมเวิร์กสื่อด้วยวิธีต่อไปนี้
- การแยกคอมโพเนนต์ไปป์ไลน์ AV ออกเป็นกระบวนการที่ใช้แซนด์บ็อกซ์เฉพาะแอป
- การเปิดใช้คอมโพเนนต์สื่อที่อัปเดตได้ (โปรแกรมแยกไฟล์ โปรแกรมเปลี่ยนรหัส ฯลฯ)
การเปลี่ยนแปลงเหล่านี้ยังช่วยปรับปรุงความปลอดภัยให้กับผู้ใช้ปลายทางด้วย โดยลดความร้ายแรงของช่องโหว่ด้านความปลอดภัยที่เกี่ยวข้องกับสื่อส่วนใหญ่ได้อย่างมาก ซึ่งช่วยให้อุปกรณ์และข้อมูลของผู้ใช้ปลายทางปลอดภัย
OEM และผู้ให้บริการ SoC จำเป็นต้องอัปเดต HAL และการเปลี่ยนแปลงเฟรมเวิร์กเพื่อให้เข้ากันได้กับสถาปัตยกรรมใหม่ กล่าวโดยละเอียดคือ เนื่องจากโค้ด Android ที่ได้จากผู้ขายมักจะถือว่าทุกอย่างทำงานในกระบวนการเดียวกัน ผู้ขายจึงต้องอัปเดตโค้ดเพื่อส่งแฮนเดิลเนทีฟ (native_handle
) ที่มีความหมายในกระบวนการต่างๆ ดูข้อมูลอ้างอิงสำหรับการติดตั้งใช้งานการเปลี่ยนแปลงที่เกี่ยวข้องกับการทำให้สื่อมีความปลอดภัยได้ที่ frameworks/av
และ frameworks/native
การเปลี่ยนแปลงสถาปัตยกรรม
Android เวอร์ชันก่อนหน้าใช้mediaserver
กระบวนการแบบโมโนลิธิคเพียงรายการเดียวที่มีสิทธิ์มากมาย (การเข้าถึงกล้อง การเข้าถึงเสียง การเข้าถึงไดรเวอร์วิดีโอ การเข้าถึงไฟล์ การเข้าถึงเครือข่าย ฯลฯ) Android 7.0 ได้แยกกระบวนการ mediaserver
ออกเป็นกระบวนการใหม่หลายรายการที่แต่ละรายการต้องใช้ชุดสิทธิ์ที่น้อยลงมาก ดังนี้
รูปที่ 1 การเปลี่ยนแปลงสถาปัตยกรรมเพื่อเพิ่มความแข็งแกร่งให้กับ Media Server
สถาปัตยกรรมใหม่นี้ช่วยให้มั่นใจได้ว่าแม้ว่ากระบวนการหนึ่งๆ จะถูกบุกรุก โค้ดที่เป็นอันตรายก็จะไม่มีสิทธิ์เข้าถึงชุดสิทธิ์ทั้งหมดที่ mediaserver
มีก่อนหน้านี้ กระบวนการถูกจํากัดโดยนโยบาย SELinux และ seccomp
หมายเหตุ: เนื่องจากโค้ดบางอย่างต้องอาศัยผู้ให้บริการ โค้ดเหล่านี้จึงยังคงทำงานใน mediaserver
และทำให้ mediaserver
มีสิทธิ์มากกว่าที่จำเป็น กล่าวโดยละเอียดคือ Widevine Classic จะยังคงทำงานใน mediaserver
สำหรับ Android 7.0
การเปลี่ยนแปลง MediaServer
ใน Android 7.0 กระบวนการ mediaserver
มีไว้เพื่อขับเคลื่อนการเล่นและการบันทึก เช่น การส่งและซิงค์บัฟเฟอร์ระหว่างคอมโพเนนต์และกระบวนการ กระบวนการสื่อสารผ่านกลไก Binder แบบมาตรฐาน
ในเซสชันการเล่นไฟล์ในเครื่องแบบมาตรฐาน แอปจะส่งไฟล์อธิบาย (FD) ไปยัง mediaserver
(โดยปกติผ่าน MediaPlayer Java API) และ mediaserver
จะดำเนินการต่อไปนี้
- แพ็ก FD ไว้ในออบเจ็กต์ DataSource ของ Binder ที่ส่งไปยังกระบวนการแยกข้อมูล ซึ่งจะใช้เพื่ออ่านจากไฟล์โดยใช้ Binder IPC (mediaextractor ไม่ได้รับ 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 Movies ซึ่งจะจัดการการถอดรหัสข้อมูลที่เข้ารหัสด้วยวิธีที่ปลอดภัย และด้วยเหตุนี้จึงมีสิทธิ์เข้าถึงใบรับรองและที่เก็บคีย์ รวมถึงคอมโพเนนต์ที่ละเอียดอ่อนอื่นๆ กระบวนการ DRM ยังไม่พร้อมใช้งานในบางกรณีเนื่องจากความซับซ้อนของผู้ให้บริการ
การเปลี่ยนแปลง AudioServer
กระบวนการ AudioServer โฮสต์คอมโพเนนต์ที่เกี่ยวข้องกับเสียง เช่น อินพุตและเอาต์พุตเสียง บริการตัวจัดการนโยบายที่กำหนดการกำหนดเส้นทางเสียง และบริการวิทยุ FM โปรดดูรายละเอียดเกี่ยวกับการเปลี่ยนแปลงเสียงและคำแนะนำการใช้งานที่หัวข้อใช้เสียง
การเปลี่ยนแปลง CameraServer
CameraServer จะควบคุมกล้องและใช้เมื่อบันทึกวิดีโอเพื่อรับเฟรมวิดีโอจากกล้อง จากนั้นส่งไปยัง mediaserver
เพื่อดำเนินการต่อ ดูรายละเอียดเกี่ยวกับการเปลี่ยนแปลงและคำแนะนำการใช้งานสำหรับการเปลี่ยนแปลงของ CameraServer ได้ที่การเพิ่มความปลอดภัยให้กับเฟรมเวิร์กกล้อง
การเปลี่ยนแปลง ExtractorService
บริการเครื่องมือแยกข้อมูลจะโฮสต์เครื่องมือแยกข้อมูล ซึ่งเป็นคอมโพเนนต์ที่แยกวิเคราะห์รูปแบบไฟล์ต่างๆ ที่เฟรมเวิร์กสื่อรองรับ บริการแยกไฟล์มีสิทธิ์น้อยที่สุดเมื่อเทียบกับบริการอื่นๆ เนื่องจากไม่สามารถอ่าน FD ได้ แต่จะเรียกใช้อินเทอร์เฟซ Binder (mediaserver for
เซสชันการเล่นแต่ละเซสชัน) เพื่อเข้าถึงไฟล์แทน
แอป (หรือ mediaserver
) จะเรียกใช้กระบวนการแยกไฟล์เพื่อรับ IMediaExtractor
แล้วเรียกใช้ IMediaExtractor
นั้นเพื่อรับ IMediaSources
สำหรับแทร็กที่อยู่ในไฟล์ จากนั้นเรียกใช้ IMediaSources
เพื่ออ่านข้อมูลจาก IMediaExtractor
หากต้องการโอนข้อมูลระหว่างกระบวนการ แอป (หรือ mediaserver
) จะรวมข้อมูลไว้ในแพ็กเกจตอบกลับเป็นส่วนหนึ่งของธุรกรรม Binder หรือใช้หน่วยความจำที่ใช้ร่วมกัน
- การใช้หน่วยความจําที่ใช้ร่วมกันต้องเรียก Binder เพิ่มเติมเพื่อปลดปล่อยหน่วยความจําที่ใช้ร่วมกัน แต่จะใช้พลังงานน้อยลงและเร็วขึ้นสําหรับบัฟเฟอร์ขนาดใหญ่
- การใช้ in-Parcel ต้องมีการคัดลอกเพิ่มเติม แต่จะใช้พลังงานน้อยลงและเร็วกว่าสำหรับบัฟเฟอร์ที่มีขนาดเล็กกว่า 64 KB
การใช้งาน
หากต้องการรองรับการย้ายคอมโพเนนต์ MediaDrm
และ MediaCrypto
ไปยังกระบวนการ mediadrmserver
ใหม่ ผู้ให้บริการต้องเปลี่ยนวิธีการจัดสรรบัฟเฟอร์ที่ปลอดภัยเพื่อให้แชร์บัฟเฟอร์ระหว่างกระบวนการได้
ใน Android เวอร์ชันก่อนหน้า ระบบจะจัดสรรบัฟเฟอร์ที่ปลอดภัยใน mediaserver
โดย OMX::allocateBuffer
และใช้ระหว่างการถอดรหัสในกระบวนการเดียวกัน ดังที่แสดงด้านล่าง
รูปที่ 2 การจัดสรรบัฟเฟอร์ใน MediaServer ของ Android 6.0 และต่ำกว่า
ใน Android 7.0 กระบวนการจัดสรรบัฟเฟอร์ได้เปลี่ยนไปใช้กลไกใหม่ซึ่งมีความยืดหยุ่นมากขึ้น ในขณะเดียวกันก็ลดผลกระทบต่อการใช้งานที่มีอยู่ เมื่อใช้กอง MediaDrm
และ MediaCrypto
ในกระบวนการ mediadrmserver
ใหม่ ระบบจะจัดสรรบัฟเฟอร์ในลักษณะที่แตกต่างออกไป และผู้ขายต้องอัปเดตแฮนเดิลบัฟเฟอร์ที่ปลอดภัยเพื่อให้สามารถส่งผ่าน Binder ได้เมื่อ MediaCodec
เรียกใช้การดำเนินการถอดรหัสใน MediaCrypto
รูปที่ 3 การจัดสรรบัฟเฟอร์ใน MediaServer ของ Android 7.0 ขึ้นไป
ใช้แฮนเดิลเนทีฟ
OMX::allocateBuffer
ต้องแสดงผลพอยน์เตอร์ไปยังโครงสร้าง native_handle
ซึ่งมีตัวระบุไฟล์ (FD) และข้อมูลจำนวนเต็มเพิ่มเติม native_handle
มีข้อดีทั้งหมดของการใช้ FD รวมถึงการรองรับ Binder ที่มีอยู่สำหรับการแปลงเป็นอนุกรม/การแปลงอนุกรม และให้ความยืดหยุ่นมากขึ้นแก่ผู้ให้บริการที่ไม่ได้ใช้ FD ในปัจจุบัน
ใช้ native_handle_create()
เพื่อจัดสรรแฮนเดิลเนทีฟ
โค้ดเฟรมเวิร์กจะเป็นเจ้าของโครงสร้าง native_handle
ที่สร้างขึ้นและมีหน้าที่รับผิดชอบในการปล่อยทรัพยากรทั้งในระหว่างกระบวนการที่สร้างขึ้น 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 ทราบว่าควรใช้แฮนเดิลแบบเนทีฟ