Google cam kết thúc đẩy công bằng chủng tộc cho Cộng đồng người da đen. Xem cách thực hiện.
Trang này được dịch bởi Cloud Translation API.
Switch to English

Con trỏ được gắn thẻ

Bắt đầu từ Android 11, đối với các quy trình 64-bit, tất cả các phân bổ heap đều có thẻ được xác định triển khai được đặt trong byte trên cùng của con trỏ trên các thiết bị có hỗ trợ hạt nhân cho ARM Top-byte Bỏ qua (TBI). Bất kỳ ứng dụng nào sửa đổi thẻ này sẽ bị chấm dứt khi thẻ được kiểm tra trong quá trình phân bổ. Điều này là cần thiết cho phần cứng trong tương lai có hỗ trợ Mở rộng thẻ nhớ ARM (MTE).

Bỏ qua byte trên cùng

Tính năng Bỏ qua byte hàng đầu của ARM có sẵn cho mã 64-bit trong tất cả phần cứng Armv8 AArch64. Tính năng này có nghĩa là phần cứng bỏ qua byte trên cùng của một con trỏ khi truy cập bộ nhớ.

TBI yêu cầu mộtnhân tương thích xử lý chính xác các con trỏ được gắn thẻ được truyền từ không gian người dùng. Nhân chung của Android từ 4.14 (Pixel 4) trở lên có các bản vá TBI bắt buộc.

Các thiết bị có hỗ trợ TBI trong hạt nhân được phát hiện động tại thời điểm bắt đầu quá trình và một thẻ phụ thuộc vào triển khai được chèn vào byte trên cùng của con trỏ cho tất cả các phân bổ heap. Sau đó, kiểm tra sẽ được chạy để đảm bảo thẻ không bị cắt ngắn khi phân bổ bộ nhớ.

Sự sẵn sàng của phần mở rộng gắn thẻ bộ nhớ

Tiện ích mở rộng gắn thẻ bộ nhớ (MTE) của ARM giúp giải quyết các vấn đề về an toàn bộ nhớ. MTE hoạt động bằng cách gắn thẻ các bit địa chỉ thứ 56-59 của mỗi cấp phát bộ nhớ trên ngăn xếp, đống và toàn cầu. Phần cứng và tập lệnh tự động kiểm tra xem thẻ đúng có được sử dụng trên mỗi lần truy cập bộ nhớ hay không.

Các ứng dụng Android lưu trữ sai thông tin trong byte trên cùng của con trỏ được đảm bảo sẽ bị hỏng trên thiết bị hỗ trợ MTE . Con trỏ được gắn thẻ giúp dễ dàng phát hiện và từ chối việc sử dụng không chính xác byte trên cùng của con trỏ trước khi có thiết bị MTE.

Hỗ trợ nhà phát triển

Nếu ứng dụng của bạn gặp sự cố và bạn được nhắc bằng liên kết này, điều đó có thể có nghĩa là một trong những điều sau:

  1. Ứng dụng đã cố gắng giải phóng một con trỏ không được phân bổ bởi trình phân bổ heap của hệ thống.
  2. Một cái gì đó trong ứng dụng của bạn đã sửa đổi byte trên cùng của con trỏ. Không thể sửa đổi byte trên cùng của con trỏ và mã của bạn cần được thay đổi để khắc phục sự cố này.

Ví dụ về con trỏ byte trên cùng được sử dụng hoặc sửa đổi không chính xác.

  • Con trỏ đến một loại cụ thể có siêu dữ liệu cụ thể của ứng dụng được lưu trữ trong 16 bit địa chỉ hàng đầu.
  • Một con trỏ ép kiểu để nhân đôi rồi quay lại, làm mất các bit địa chỉ thấp hơn.
  • Tính toán mã sự khác biệt giữa địa chỉ của các biến cục bộ từ các khung ngăn xếp khác nhau như một cách để đo độ sâu đệ quy.

Một số ứng dụng có thể phụ thuộc vào các thư viện hoạt động không chính xác khi byte trên cùng của con trỏ được đặt. Chúng tôi nhận thấy rằng việc nhanh chóng khắc phục các sự cố cơ bản này trong các thư viện có thể không phải là điều tầm thường. Do đó, các ứng dụng sử dụng targetSdkLevel < 30 sẽ không được bật tính năng gắn thẻ con trỏ theo mặc định. Chúng tôi cũng cung cấp một lối thoát cho các ứng dụng được xây dựng với targetSdkLevel >= 30 để giảm bớt giai đoạn chuyển tiếp.

Cửa sổ thoát được sử dụng bằng cách thêm phần sau vào tệp AndroidManifest.xml của bạn:

  <application android:allowNativeHeapPointerTagging="false">
  ...
  </application>

Thao tác này sẽ tắt tính năng Gắn thẻ con trỏ cho ứng dụng của bạn. Xin lưu ý rằng điều này không giải quyết vấn đề sức khỏe của mã cơ bản. Lối thoát này sẽ biến mất trong các phiên bản Android trong tương lai, vì các vấn đề về bản chất này sẽ không tương thích với MTE .