Làm cứng khuôn khổ phương tiện

Để cải thiện tính bảo mật của thiết bị, Android 7.0 chia nhỏ quy trình máy chủ trung gian nguyên khối thành nhiều mediaserver trình với các quyền và khả năng chỉ giới hạn ở những quy trình được yêu cầu bởi mỗi quy trình. Những thay đổi này giảm thiểu các lỗ hổng bảo mật của khuôn khổ phương tiện bằng cách:

  • Tách các thành phần đường ống AV thành các quy trình hộp cát dành riêng cho ứng dụng.
  • Bật các thành phần phương tiện có thể cập nhật (trình giải nén, codec, v.v.).

Những thay đổi này cũng cải thiện tính bảo mật cho người dùng cuối bằng cách giảm đáng kể mức độ nghiêm trọng của hầu hết các lỗ hổng bảo mật liên quan đến phương tiện, giữ an toàn cho thiết bị và dữ liệu của người dùng cuối.

Các OEM và nhà cung cấp SoC cần cập nhật các thay đổi về HAL và khuôn khổ của họ để làm cho chúng tương thích với kiến ​​trúc mới. Cụ thể, vì mã Android do nhà cung cấp cung cấp thường giả định mọi thứ chạy trong cùng một quy trình, nên nhà cung cấp phải cập nhật mã của họ để chuyển xung quanh các xử lý gốc ( native_handle ) có ý nghĩa trên các quy trình. Để tham khảo cách triển khai các thay đổi liên quan đến việc làm cứng phương tiện, hãy tham khảo frameworks/avframeworks/native .

Thay đổi kiến ​​trúc

Các phiên bản trước của Android sử dụng một quy trình trung gian duy nhất, nguyên mediaserver với nhiều quyền tuyệt vời (truy cập camera, truy cập âm thanh, truy cập trình điều khiển video, truy cập tệp, truy cập mạng, v.v.). Android mediaserver chia quy trình của máy chủ trung gian thành một số quy trình mới mà mỗi quy trình yêu cầu một bộ quyền nhỏ hơn nhiều:

làm cứng máy trung gian

Hình 1. Những thay đổi về kiến ​​trúc để tăng cường độ cứng của máy chủ trung gian

Kiến trúc mới này đảm bảo rằng ngay cả khi một quy trình bị xâm phạm, mã độc hại không có quyền truy cập vào toàn bộ các quyền mà máy chủ trung gian nắm giữ trước đó. Các quy trình bị hạn chế bởi chính sách SElinux và seccomp.

Lưu ý: Do phụ thuộc vào nhà cung cấp, một số codec vẫn chạy trong máy chủ trung mediaserver và do đó cấp cho máy chủ trung mediaserver nhiều quyền hơn mức cần thiết. Cụ thể, mediaserver Classic tiếp tục chạy trong trình trung gian cho Android 7.0.

Thay đổi MediaServer

Trong Android mediaserver , quy trình trung gian tồn tại để thúc đẩy phát lại và ghi âm, ví dụ: truyền và đồng bộ hóa bộ đệm giữa các thành phần và quy trình. Các quy trình giao tiếp thông qua cơ chế Binder tiêu chuẩn.

Trong một phiên phát lại tệp cục bộ tiêu chuẩn, ứng dụng chuyển bộ mô tả tệp ( mediaserver ) đến máy chủ trung gian (thường thông qua API mediaserver Java) và máy chủ trung gian:

  1. Gói FD vào một đối tượng Binder DataSource được chuyển đến quy trình giải nén, quy trình này sử dụng nó để đọc từ tệp bằng Binder IPC. ( mediaserver không nhận được FD mà thay vào đó, Binder gọi trở lại trung gian để lấy dữ liệu.)
  2. Kiểm tra tệp, tạo trình giải nén thích hợp cho loại tệp (ví dụ: MP3Extractor hoặc mediaserver ) và trả về giao diện Binder cho trình giải nén vào quy trình máy chủ trung gian.
  3. Thực hiện cuộc gọi Binder IPC tới trình giải nén để xác định loại dữ liệu trong tệp (ví dụ: dữ liệu MP3 hoặc H.264).
  4. Các lệnh gọi vào quy trình mediacodec để tạo codec thuộc loại bắt buộc; nhận các giao diện Binder cho các codec này.
  5. Thực hiện các cuộc gọi Binder IPC lặp đi lặp lại tới trình trích xuất để đọc các mẫu được mã hóa, sử dụng Binder IPC để gửi dữ liệu được mã hóa đến quy trình mediacodec để giải mã và nhận dữ liệu đã được giải mã.

Trong một số trường hợp sử dụng, không có codec nào tham gia (chẳng hạn như phát lại không tải trong đó dữ liệu được mã hóa được gửi trực tiếp đến thiết bị đầu ra) hoặc codec có thể hiển thị trực tiếp dữ liệu đã giải mã thay vì trả về bộ đệm dữ liệu đã giải mã (phát lại video).

Thay đổi MediaCodecService

Dịch vụ codec là nơi các bộ mã hóa và bộ giải mã hoạt động. Do sự phụ thuộc của nhà cung cấp, không phải tất cả các codec đều tồn tại trong quy trình codec. Trong Android 7.0:

  • Bộ giải mã không an toàn và bộ mã hóa phần mềm nằm trong quy trình codec.
  • Bộ giải mã an toàn và bộ mã hóa phần cứng nằm trong máy chủ trung mediaserver (không thay đổi).

Một ứng dụng (hoặc máy chủ trung gian) gọi quy trình codec để tạo codec thuộc loại bắt buộc, sau đó gọi codec đó để chuyển vào dữ liệu được mã hóa và truy xuất dữ liệu đã giải mã (để giải mã) hoặc để chuyển dữ liệu đã giải mã và truy xuất dữ liệu đã mã hóa (để mã hóa) . Việc truyền dữ liệu đến và đi từ codec đã sử dụng bộ nhớ dùng chung, vì vậy quá trình đó không thay đổi.

Thay đổi MediaDrmServer

Máy chủ DRM được sử dụng khi phát nội dung được bảo vệ bằng DRM, chẳng hạn như phim trong Google Play Phim. Nó xử lý việc giải mã dữ liệu được mã hóa theo cách an toàn và như vậy có quyền truy cập vào chứng chỉ và lưu trữ khóa và các thành phần nhạy cảm khác. Do phụ thuộc vào nhà cung cấp, quy trình DRM không được sử dụng trong mọi trường hợp.

Thay đổi AudioServer

Quy trình AudioServer lưu trữ các thành phần liên quan đến âm thanh như đầu vào và đầu ra âm thanh, dịch vụ trình quản lý chính sách xác định định tuyến âm thanh và dịch vụ đài FM. Để biết chi tiết về các thay đổi Âm thanh và hướng dẫn triển khai, hãy xem Triển khai Âm thanh .

Thay đổi CameraServer

mediaserver điều khiển máy ảnh và được sử dụng khi quay video để thu được các khung hình video từ máy ảnh và sau đó chuyển chúng cho máy chủ trung gian để xử lý thêm. Để biết chi tiết về các thay đổi và hướng dẫn triển khai cho các thay đổi của CameraServer, hãy tham khảo Làm cứng khung máy ảnh .

Thay đổi ExtractorService

Dịch vụ trình giải nén lưu trữ các trình giải nén , các thành phần phân tích cú pháp các định dạng tệp khác nhau được hỗ trợ bởi khung phương tiện. Dịch vụ trình trích xuất có đặc quyền ít nhất trong tất cả các dịch vụ — nó không thể đọc FD nên thay vào đó, nó thực hiện các lệnh gọi đến giao diện Binder (được cung cấp bởi máy chủ trung gian mediaserver for mỗi phiên phát lại) để truy cập tệp.

Một ứng dụng (hoặc máy chủ trung gian) thực hiện cuộc gọi tới quy trình trích xuất để lấy mediaserver , gọi IMediaExtractor đó để lấy IMediaExtractor cho IMediaSources nhạc có trong tệp, sau đó gọi IMediaSources để đọc dữ liệu từ chúng.

Để chuyển dữ liệu giữa các quy trình, ứng dụng (hoặc máy chủ trung mediaserver ) bao gồm dữ liệu trong Gói trả lời như một phần của giao dịch Binder hoặc sử dụng bộ nhớ được chia sẻ:

  • Việc sử dụng bộ nhớ dùng chung yêu cầu thêm một lệnh gọi Binder để giải phóng bộ nhớ dùng chung nhưng nhanh hơn và sử dụng ít năng lượng hơn cho các bộ đệm lớn.
  • Sử dụng In-Parcel yêu cầu sao chép thêm nhưng nhanh hơn và sử dụng ít năng lượng hơn cho bộ đệm nhỏ hơn 64KB.

Thực hiện

Để hỗ trợ việc di chuyển các thành phần MediaDrmMediaCrypto vào quy trình máy chủ mediadrmserver gian mới, các nhà cung cấp phải thay đổi phương pháp cấp phát cho các bộ đệm an toàn để cho phép các bộ đệm được chia sẻ giữa các quá trình.

Trong các bản phát hành Android trước, bộ đệm bảo mật được OMX::allocateBuffer mediaserver máy chủ trung gian và được sử dụng trong quá trình giải mã trong cùng một quy trình, như được hiển thị bên dưới:

Hình 2. Android 6.0 và phân bổ bộ đệm thấp hơn trong máy chủ trung gian.

Trong Android 7.0, quy trình phân bổ bộ đệm đã thay đổi thành một cơ chế mới cung cấp tính linh hoạt trong khi giảm thiểu tác động đến các triển khai hiện có. Với các ngăn xếp MediaDrmMediaCrypto trong quy trình máy chủ mediadrmserver gian mới, các bộ đệm được phân bổ khác nhau và các nhà cung cấp phải cập nhật các xử lý bộ đệm an toàn để chúng có thể được truyền qua chất kết dính khi MediaCodec gọi hoạt động giải mã trên MediaCrypto .

Hình 3. Phân bổ bộ đệm Android 7.0 và cao hơn trong máy chủ trung gian.

Sử dụng tay cầm gốc

OMX::allocateBuffer allowBuffer phải trả về một con trỏ đến cấu trúc native_handle , chứa các bộ mô tả tệp (FD) và dữ liệu số nguyên bổ sung. native_handle có tất cả các lợi thế của việc sử dụng FD, bao gồm hỗ trợ chất kết dính hiện có để tuần tự hóa / deserialization, đồng thời cho phép linh hoạt hơn đối với các nhà cung cấp hiện không sử dụng FD.

Sử dụng native_handle_create() để phân bổ xử lý gốc. Mã khung có quyền sở hữu cấu trúc native_handle được cấp phát và chịu trách nhiệm giải phóng tài nguyên trong cả quá trình mà native_handle được cấp phát ban đầu và trong quá trình mà nó được giải phóng. Khung công tác phát hành các xử lý gốc với native_handle_close() theo sau là native_handle_delete() và tuần tự hóa / giải native_handle bằng cách sử dụng Parcel::writeNativeHandle()/readNativeHandle() .

Các nhà cung cấp SoC sử dụng FD để đại diện cho bộ đệm an toàn có thể điền FD vào native_handle với FD của họ. Các nhà cung cấp không sử dụng FD có thể đại diện cho bộ đệm an toàn bằng cách sử dụng các trường bổ sung trong bộ native_buffer .

Đặt vị trí giải mã

Các nhà cung cấp phải cập nhật phương pháp giải mã OEMCrypto hoạt động trên native_handle để thực hiện bất kỳ hoạt động cần thiết nào của nhà cung cấp cụ thể để làm cho native_handle có thể sử dụng được trong không gian quy trình mới (các thay đổi thường bao gồm cập nhật cho thư viện OEMCrypto).

allocateBuffer là một hoạt động OMX tiêu chuẩn, Android 7.0 bao gồm một tiện ích mở rộng OMX mới ( OMX.google.android.index.allocateNativeHandle ) để truy vấn hỗ trợ này và lệnh gọi OMX_SetParameter thông báo cho việc triển khai OMX mà nó sẽ sử dụng các xử lý gốc.