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

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

Bỏ qua byte hàng đầu

Tính năng Bỏ qua byte hàng đầu của ARM khả dụng 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 sẽ 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ột thẻ nhân hệ điều hành giúp xử lý chính xác con trỏ được gắn thẻ được truyền từ không gian người dùng. Hạt nhân phổ biến của Android từ 4.14 (Pixel 4) trở lên có TBI bắt buộc bản vá.

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

Trạng thái sẵn sàng của Tiện ích gắn thẻ bộ nhớ

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

Ứng dụng Android lưu trữ thông tin không chính xác trong byte trên cùng của con trỏ đả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 cách sử dụng không chính xác của từ khoá byte của con trỏ trước khi có thiết bị MTE.

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

Nếu ứng dụng của bạn gặp sự cố và bạn được nhắc kèm theo đường liên kết này, thì có thể là một trong các lệnh sau:

  1. Ứng dụng đã cố giải phóng một con trỏ không được trình phân bổ vùng nhớ khối xếp của hệ thống.
  2. Một số nội dung trong ứng dụng của bạn đã sửa đổi byte trên cùng của một con trỏ. byte trên cùng của con trỏ không thể sửa đổi và bạn cần thay đổi mã để khắc phục lỗi này vấn đề.

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

  • Con trỏ đến một loại cụ thể sẽ được lưu trữ siêu dữ liệu dành riêng cho ứng dụng trong 16 bit địa chỉ hàng đầu.
  • Một con trỏ truyền tới 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 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 làm 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 hiểu rằng có thể giúp khắc phục nhanh chóng những vấn đề cơ bản này trong thư viện. Do vậy, các ứng dụng 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 bản cập nhật cho các ứng dụng được tạo bằng targetSdkLevel >= 30 để giúp giai đoạn chuyển tiếp diễn ra dễ dàng hơn.

Lỗ thoát hiểm được sử dụng bằng cách thêm đoạn mã sau vào Tệp AndroidManifest.xml:

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

Thao tác này sẽ tắt tính năng Gắn thẻ con trỏ . Việc này không giải quyết vấn đề cơ bản về tình trạng của mã. Lối thoát này sẽ biến mất trong tương lai phiên bản Android của mình, bởi vì các vấn đề có tính chất này sẽ không tương thích với MTE.