การแข็งตัวของกรอบสื่อ

เพื่อปรับปรุงความปลอดภัยของอุปกรณ์ Android 7.0 ได้แบ่งกระบวนการ mediaserver ขนาดใหญ่ออกเป็นหลายกระบวนการ โดยมีสิทธิ์และความสามารถจำกัดเฉพาะกระบวนการที่จำเป็นสำหรับแต่ละกระบวนการเท่านั้น การเปลี่ยนแปลงเหล่านี้ช่วยลดความเสี่ยงด้านความปลอดภัยของกรอบสื่อสื่อโดย:

  • การแยกส่วนประกอบไปป์ไลน์ AV ออกเป็นกระบวนการแซนด์บ็อกซ์เฉพาะแอป
  • การเปิดใช้งานส่วนประกอบสื่อที่สามารถอัพเดตได้ (ตัวแยกไฟล์ ตัวแปลงสัญญาณ ฯลฯ)

การเปลี่ยนแปลงเหล่านี้ยังปรับปรุงความปลอดภัยสำหรับผู้ใช้ปลายทางด้วยการลดความรุนแรงของช่องโหว่ด้านความปลอดภัยที่เกี่ยวข้องกับสื่อส่วนใหญ่ ทำให้อุปกรณ์และข้อมูลของผู้ใช้ปลายทางปลอดภัย

ผู้จำหน่าย OEM และ SoC จำเป็นต้องอัปเดต HAL และการเปลี่ยนแปลงเฟรมเวิร์กเพื่อให้เข้ากันได้กับสถาปัตยกรรมใหม่ โดยเฉพาะอย่างยิ่ง เนื่องจากโค้ด Android ของผู้จำหน่ายมักจะถือว่าทุกอย่างทำงานอยู่ในกระบวนการเดียวกัน ผู้จำหน่ายจึงต้องอัปเดตโค้ดของตนเพื่อส่งต่อไปยังเนทิฟแฮนเดิล ( native_handle ) ที่มีความหมายข้ามกระบวนการ สำหรับการดำเนินการอ้างอิงของการเปลี่ยนแปลงที่เกี่ยวข้องกับการทำให้สื่อแข็งขึ้น โปรดดูที่ frameworks/av และ frameworks/native

การเปลี่ยนแปลงทางสถาปัตยกรรม

Android เวอร์ชันก่อนหน้าใช้กระบวนการ mediaserver ขนาดใหญ่ก้อนเดียวพร้อมสิทธิ์มากมาย (การเข้าถึงกล้อง การเข้าถึงเสียง การเข้าถึงไดรเวอร์วิดีโอ การเข้าถึงไฟล์ การเข้าถึงเครือข่าย ฯลฯ) Android 7.0 แบ่งกระบวนการ mediaserver ออกเป็นกระบวนการใหม่หลายกระบวนการ ซึ่งแต่ละกระบวนการต้องการชุดสิทธิ์ที่น้อยกว่ามาก:

เซิร์ฟเวอร์สื่อแข็งตัว

รูปที่ 1 การเปลี่ยนแปลงสถาปัตยกรรมสำหรับการเสริมความแข็งแกร่งของเซิร์ฟเวอร์สื่อ

สถาปัตยกรรมใหม่นี้ช่วยให้แน่ใจว่าแม้ว่ากระบวนการจะถูกบุกรุก โค้ดที่เป็นอันตรายจะไม่สามารถเข้าถึงชุดสิทธิ์ทั้งหมดก่อนหน้านี้ที่ 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 :

  1. ล้อม FD ลงในอ็อบเจ็กต์ Binder DataSource ที่ส่งผ่านไปยังกระบวนการแยก ซึ่งใช้ในการอ่านจากไฟล์โดยใช้ Binder IPC (ตัวแยกสื่อไม่ได้รับ FD แต่ทำให้ Binder โทรกลับไปยัง mediaserver เพื่อรับข้อมูลแทน)
  2. ตรวจสอบไฟล์ สร้างตัวแยกที่เหมาะสมสำหรับประเภทไฟล์ (เช่น MP3Extractor หรือ MPEG4Extractor) และส่งคืนอินเทอร์เฟซ Binder สำหรับตัวแยกไปยังกระบวนการของ mediaserver
  3. ทำการเรียก Binder IPC ไปยังตัวแยกเพื่อกำหนดประเภทของข้อมูลในไฟล์ (เช่น ข้อมูล MP3 หรือ H.264)
  4. เรียกเข้าสู่กระบวนการ mediacodec เพื่อสร้างตัวแปลงสัญญาณประเภทที่ต้องการ รับอินเทอร์เฟซ Binder สำหรับตัวแปลงสัญญาณเหล่านี้
  5. ทำการเรียก 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 และใช้ในระหว่างการถอดรหัสในกระบวนการเดียวกัน ดังที่แสดงด้านล่าง:

รูปที่ 2 Android 6.0 และการจัดสรรบัฟเฟอร์ที่ต่ำกว่าในมีเดียเซิร์ฟเวอร์

ใน Android 7.0 กระบวนการจัดสรรบัฟเฟอร์ได้เปลี่ยนไปเป็นกลไกใหม่ที่ให้ความยืดหยุ่นในขณะที่ลดผลกระทบต่อการใช้งานที่มีอยู่ให้เหลือน้อยที่สุด ด้วย MediaDrm และ MediaCrypto stacks ในกระบวนการ mediadrmserver ใหม่ บัฟเฟอร์จะถูกจัดสรรแตกต่างกัน และผู้ขายต้องอัปเดตตัวจัดการบัฟเฟอร์ที่ปลอดภัย เพื่อให้สามารถขนส่งข้าม Binder ได้เมื่อ MediaCodec เรียกใช้การดำเนินการถอดรหัสบน MediaCrypto

รูปที่ 3 การจัดสรรบัฟเฟอร์ Android 7.0 และสูงกว่าในมีเดียเซิร์ฟเวอร์

ใช้แฮนเดิลดั้งเดิม

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 ซึ่งควรใช้ตัวจัดการดั้งเดิม