Gỡ lỗi bộ nhớ và giảm thiểu lỗi bộ nhớ

Android hỗ trợ nhiều công cụ gỡ lỗi bộ nhớ. Mỗi công cụ đều có cả ưu điểm lẫn khuyết điểm. Vì vậy, hãy đọc thông tin dưới đây để quyết định xem công cụ nào phù hợp nhất với trường hợp sử dụng của bạn. Tài liệu này cung cấp cho bạn thông tin tổng quan về các công cụ có thể dùng để bạn có thể quyết định phương án tìm hiểu sâu hơn. Tuy nhiên, đây chỉ là tài liệu tóm tắt, vì vậy hãy đọc tài liệu của riêng từng công cụ để biết thêm thông tin.

Tóm tắt

  • Sử dụng một ngôn ngữ an toàn đối với bộ nhớ bất cứ khi nào có thể để tránh lỗi bộ nhớ triệt để
  • Luôn sử dụng PAC/BTI để giảm thiểu việc bị tấn công ROP/JOP
  • Luôn sử dụng GWP-ASan để phát hiện các lỗi bộ nhớ hiếm gặp trong bản phát hành công khai
  • Sử dụng HWASan để phát hiện lỗi bộ nhớ trong quá trình kiểm thử
  • Các thiết bị có khả năng hỗ trợ MTE chưa được phát hành rộng rãi vào năm 2023, nhưng hãy sử dụng MTE nếu bạn có thể phát hiện lỗi trong bản phát hành công khai
  • Chỉ sử dụng ASan trong quá trình kiểm thử khi không còn phương án nào tốt hơn

Ngôn ngữ an toàn đối với bộ nhớ

Ngôn ngữ an toàn đối với bộ nhớ là cách duy nhất để tránh và giảm thiểu triệt để lỗi bộ nhớ. Các công cụ khác trên trang này có thể giúp bạn làm cho đoạn mã chưa an toàn đối với bộ nhớ trở nên an toàn hơn. Tuy nhiên, việc sử dụng ngôn ngữ an toàn đối với bộ nhớ sẽ giúp loại bỏ triệt để vấn đề.

Các ngôn ngữ an toàn đối với bộ nhớ được hỗ trợ chính thức cho Android là Java và Kotlin. Bạn có thể dễ dàng phát triển hầu hết ứng dụng Android bằng một trong hai ngôn ngữ đó.

Tuy nhiên, có một số nhà phát triển ứng dụng đã chuyển sang viết mã bằng Rust. Nếu đang đọc trang này, thì có thể bạn nên dùng mã gốc (để chuyển đổi được dễ dàng hơn, đạt hiệu suất cao hơn hoặc cả hai). Rust là lựa chọn tốt nhất cho mã gốc an toàn đối với bộ nhớ trên Android. Có thể nhóm NDK không giúp được bạn giải quyết vấn đề gặp phải nếu bạn làm theo phương án đó, nhưng hãy chia sẻ về các vấn đề đó cho chúng tôi!

PAC/BTI

Xác thực Con trỏ và Nhận dạng Mục tiêu nhánh (còn gọi là PAC/BTI) là các công cụ giảm thiểu lỗi phù hợp để dùng cho phiên bản phát hành công khai. Tuy là những công nghệ riêng biệt, nhưng các công cụ này đều do một cờ biên dịch kiểm soát nên luôn được sử dụng cùng nhau.

Các tính năng này tương thích ngược với những thiết bị không hỗ trợ chúng vì các hướng dẫn mới được sử dụng không hoạt động trên các thiết bị đời trước. Bạn cũng cần có một nhân hệ điều hành đủ mới và một phiên bản hệ điều hành đủ mới. Hãy tìm pacabti trong /proc/cpuinfo để xem bạn có phần cứng đủ mới cũng như có nhân hệ điều hành đủ mới hay chưa. Android 12 (API cấp 31) có tính năng hỗ trợ cần thiết cho không gian người dùng.

Ưu điểm:

  • Có thể bật trong mọi bản dựng mà không gây ra sự cố nào trên các thiết bị hoặc nhân hệ điều hành đời trước (nhưng hãy đảm bảo rằng bạn đã thực sự kiểm thử trên một tổ hợp thiết bị/nhân hệ điều hành/hệ điều hành hỗ trợ công cụ đó!)

Nhược điểm:

  • Chỉ dành cho ứng dụng 64 bit
  • Không giảm thiểu lỗi trên những thiết bị không hỗ trợ công cụ này
  • Mức hao tổn kích thước mã 1%

GWP-Asan

Bạn có thể sử dụng GWP-ASan để phát hiện lỗi bộ nhớ trong trường hợp thực tế, nhưng tốc độ lấy mẫu là quá thấp để giảm thiểu lỗi một cách hiệu quả.

Ưu điểm:

  • Không hao tổn đáng kể đối với CPU hoặc bộ nhớ
  • Đơn giản, dễ triển khai: không yêu cầu tạo bản dựng lại bằng mã gốc
  • Dùng được cho ứng dụng 32 bit

Nhược điểm:

  • Tốc độ lấy mẫu thấp nên cần phải có một số lượng lớn người dùng để tìm lỗi một cách hiệu quả
  • Chỉ phát hiện lỗi vùng nhớ khối xếp, không phát hiện lỗi ngăn xếp

HWASan

Trình dọn dẹp địa chỉ phần cứng (còn được gọi là HWASan) là phương thức phù hợp nhất để phát hiện lỗi bộ nhớ trong quá trình kiểm thử. Phương thức này hữu ích nhất khi được sử dụng trong quy trình kiểm thử tự động, đặc biệt là khi bạn đang chạy kiểm thử mờ (fuzz test). Tuy nhiên, tuỳ thuộc vào hiệu suất của ứng dụng, bạn cũng có thể sử dụng công cụ này trên các dòng điện thoại cao cấp trong chế độ thử nghiệm nội bộ.

Ưu điểm:

  • Không có dương tính giả
  • Phát hiện các lớp lỗi khác mà ASan không phát hiện được (sử dụng ngăn xếp sau khi trả về)
  • Tỷ lệ âm tính giả thấp hơn MTE (1/256 so với 1/16)
  • Mức hao tổn bộ nhớ thấp hơn ASan, giải pháp thay thế gần giống nhất

Nhược điểm:

  • Hao tổn đáng kể đối với CPU (~ 100%), kích thước mã (~ 50%) và bộ nhớ (10% – 35%)
  • Từ API cấp độ 34 và NDK phiên bản r26 trở xuống, yêu cầu cài đặt ROM hình ảnh hệ thống tương thích với HWASan
  • Chỉ dùng được cho ứng dụng 64 bit

MTE

Tiện ích gắn thẻ bộ nhớ (còn gọi là MTE) là một giải pháp thay thế có chi phí thấp hơn so với HWASan. Ngoài các chức năng gỡ lỗi và kiểm thử, bạn có thể dùng API này để phát hiện và giảm thiểu tình trạng hỏng bộ nhớ trong phiên bản chính thức. Nếu có phần cứng để kiểm thử các bản dựng MTE, bạn nên bật MTE.

Ưu điểm:

  • Mức hao tổn đủ thấp để chấp nhận được đối với nhiều ứng dụng phát hành công khai
  • Không có dương tính giả
  • Không đòi hỏi tạo bản dựng lại mã để phát hiện lỗi vùng nhớ khối xếp (nhưng có cần để phát hiện được lỗi ngăn xếp)

Nhược điểm:

  • Chưa có thiết bị hỗ trợ MTE nào được mở bán đại trà trong năm 2024, nhưng tài liệu của Arm giải thích cách bật MTE để kiểm thử trên Pixel 8/Pixel 8 Pro.
  • Tỷ lệ âm tính giả là 1/16 so với 1/256 của HWASan
  • Chỉ dành cho ứng dụng 64 bit
  • Đòi hỏi xây dựng các thư viện riêng biệt để nhắm đến cả thiết bị hỗ trợ MTE và thiết bị không hỗ trợ MTE

ASan

Trình dọn dẹp địa chỉ (còn gọi là ASan) là công cụ lâu đời nhất và phổ biến nhất trong số các công cụ hiện tại. Công cụ này rất hữu ích trong việc phát hiện lỗi bộ nhớ trong quá trình kiểm thử và gỡ lỗi các vấn đề chỉ ảnh hưởng đến các thiết bị cũ khi không còn công cụ nào khác. Nếu được, hãy ưu tiên dùng HWASan.

Ưu điểm:

  • Được cung cấp rộng rãi Có thể dùng được trên những thiết bị cũ như KitKat
  • Không có dương tính giả hoặc âm tính khi sử dụng đúng cách

Nhược điểm:

  • Khó tạo bản dựng và đóng gói đúng cách
  • Mức hao tổn cao nhất trong tất cả lựa chọn: ~ 100% CPU, ~ 50% kích thước mã, ~ 100% mức sử dụng bộ nhớ
  • Không còn được hỗ trợ nữa
  • Có nhiều lỗi đã được ghi nhận và sẽ không được khắc phục