AddressSanitizer được hỗ trợ phần cứng

Hãy xem bài viết Tìm hiểu báo cáo HWASan để biết thông tin về cách đọc các sự cố HWASan!

Hardware-assisted AddressSanitizer (HWASan) là một công cụ phát hiện lỗi bộ nhớ tương tự như AddressSanitizer. HWASan sử dụng ít RAM hơn nhiều so với ASan, do đó, công cụ này phù hợp để dọn dẹp toàn bộ hệ thống. HWASan chỉ có trên Android 10 trở lên và chỉ có trên phần cứng AArch64.

Mặc dù chủ yếu hữu ích cho mã C/C++, nhưng HWASan cũng có thể giúp gỡ lỗi mã Java gây ra sự cố trong C/C++ dùng để triển khai các giao diện Java. Điều này rất hữu ích vì nó phát hiện các lỗi về bộ nhớ khi chúng xảy ra, hướng bạn trực tiếp đến mã chịu trách nhiệm.

So với ASan cũ, HWASan có:

  • Mức hao tổn CPU tương tự (~2x)
  • Mức hao tổn kích thước mã tương tự (40 – 50%)
  • Mức hao tổn RAM thấp hơn nhiều (10% – 35%)

HWASan phát hiện cùng một nhóm lỗi như ASan:

  • Chặn tràn (overflow)/chặn trống (underflow) cho ngăn xếp (stack) và bộ nhớ khối xếp (heap)
  • Sử dụng bộ nhớ khối xếp sau khi giải phóng
  • Sử dụng ngăn xếp bên ngoài phạm vi
  • Giải phóng hai lần/giải phóng bộ nhớ chưa được cấp phát trước đó

Ngoài ra, HWASan còn phát hiện việc sử dụng ngăn xếp sau khi trả về.

HWASan (giống như ASan) tương thích với UBSan, cả hai đều có thể được bật cùng lúc trên một mục tiêu.

Thông tin chi tiết và hạn chế về việc triển khai

HWASan dựa trên phương pháp gắn thẻ bộ nhớ, trong đó một giá trị thẻ ngẫu nhiên nhỏ được liên kết với cả con trỏ và dải địa chỉ bộ nhớ. Để truy cập vào bộ nhớ hợp lệ, con trỏ và thẻ bộ nhớ phải khớp với nhau. HWASan dựa vào tính năng bỏ qua byte quan trọng nhất (TBI) của ARMv8, còn được gọi là gắn thẻ địa chỉ ảo, để lưu trữ thẻ con trỏ trong các bit cao nhất của địa chỉ.

Bạn có thể đọc thêm về thiết kế của HWASan trên trang tài liệu Clang.

Theo thiết kế, HWASan không có vùng đỏ có kích thước giới hạn của ASan để phát hiện tràn hoặc vùng cách ly có dung lượng giới hạn của ASan để phát hiện lỗi sử dụng sau khi giải phóng. Vì lý do này, HWASan có thể phát hiện lỗi bất kể mức tràn lớn đến đâu hoặc bộ nhớ đã được giải phóng bao lâu. Điều này mang lại cho HWASan một lợi thế lớn so với ASan.

Tuy nhiên, HWASan có một số lượng hạn chế các giá trị thẻ có thể (256), điều này có nghĩa là có 0,4% khả năng bỏ lỡ bất kỳ lỗi nào trong một lần thực thi chương trình.

Yêu cầu

Các phiên bản gần đây (4.14 trở lên) của nhân Android thông thường hỗ trợ HWASan ngay khi xuất xưởng. Các nhánh dành riêng cho Android 10 không hỗ trợ HWASan.

Tính năng hỗ trợ không gian người dùng cho HWASan có từ Android 11.

Nếu đang làm việc với một nhân khác, HWASan yêu cầu nhân Linux chấp nhận con trỏ được gắn thẻ trong các đối số lệnh gọi hệ thống. Tính năng hỗ trợ cho việc này được triển khai trong các bản vá ngược dòng sau:

Nếu bạn đang tạo bằng một chuỗi công cụ tuỳ chỉnh, hãy đảm bảo rằng chuỗi công cụ đó bao gồm mọi thứ cho đến cam kết LLVM c336557f.

Sử dụng HWASan

Sử dụng các lệnh sau để tạo toàn bộ nền tảng bằng HWASan:

lunch aosp_walleye-userdebug # (or any other product)
export SANITIZE_TARGET=hwaddress
m -j

Để thuận tiện, bạn có thể thêm chế độ cài đặt SANITIZE_TARGET vào một định nghĩa sản phẩm, tương tự như aosp_coral_hwasan.

Đối với những người dùng quen thuộc với AddressSanitizer, nhiều điểm phức tạp trong bản dựng đã được loại bỏ:

  • Không cần chạy lệnh make hai lần.
  • Các bản dựng gia tăng hoạt động ngay khi bạn cài đặt phiên bản.
  • Không cần flash dữ liệu người dùng.

Một số hạn chế của AddressSanitizer cũng không còn:

  • Hỗ trợ các tệp thực thi tĩnh.
  • Bạn có thể bỏ qua việc dọn dẹp mọi mục tiêu khác ngoài libc. Không giống như ASan, không có yêu cầu nào về việc nếu một thư viện được dọn dẹp thì mọi tệp thực thi liên kết với thư viện đó cũng phải được dọn dẹp.

Bạn có thể thoải mái chuyển đổi giữa HWASan và hình ảnh thông thường ở cùng số bản dựng (hoặc cao hơn). Bạn không cần xoá dữ liệu trên thiết bị.

Để bỏ qua quy trình dọn dẹp một mô-đun, hãy sử dụng LOCAL_NOSANITIZE := hwaddress (Android.mk) hoặc sanitize: { hwaddress: false } (Android.bp).

Làm sạch các mục tiêu riêng lẻ

Bạn có thể bật HWASan cho mỗi mục tiêu trong bản dựng thông thường (chưa được dọn dẹp), miễn là libc.so cũng được dọn dẹp. Thêm hwaddress: true vào khối sanitize trong "libc_defaults" trong bionic/libc/Android.bp. Sau đó, hãy làm tương tự trong mục tiêu mà bạn đang thực hiện.

Xin lưu ý rằng việc dọn dẹp libc cho phép gắn thẻ cho các hoạt động phân bổ bộ nhớ khối xếp trên toàn hệ thống, cũng như kiểm tra các thẻ cho các hoạt động bộ nhớ bên trong libc.so. Điều này có thể phát hiện lỗi ngay cả trong các tệp nhị phân mà HWASan không được bật nếu hoạt động truy cập bộ nhớ không hợp lệ nằm trong libc.so (ví dụ: pthread_mutex_unlock() trên một mutex được delete().

Bạn không cần thay đổi bất kỳ tệp bản dựng nào nếu toàn bộ nền tảng được tạo bằng HWASan.

Dấu vết ngăn xếp tốt hơn

HWASan sử dụng một bộ tháo dỡ nhanh dựa trên con trỏ khung để ghi lại dấu vết ngăn xếp cho mọi sự kiện phân bổ và giải phóng bộ nhớ trong chương trình. Android cho phép con trỏ khung trong mã AArch64 theo mặc định, vì vậy, điều này hoạt động rất hiệu quả trên thực tế. Nếu bạn cần huỷ bỏ thông qua mã được quản lý, hãy đặt HWASAN_OPTIONS=fast_unwind_on_malloc=0 trong môi trường quy trình. Xin lưu ý rằng dấu vết ngăn xếp truy cập bộ nhớ không hợp lệ sử dụng bộ tháo dỡ "chậm" theo mặc định; chế độ cài đặt này chỉ ảnh hưởng đến dấu vết phân bổ và giải phóng. Tuỳ chọn này có thể tiêu tốn rất nhiều CPU, tuỳ thuộc vào mức tải.

Biểu tượng hoá

Xem phần Ký hiệu hoá trong bài viết "Tìm hiểu báo cáo HWASan".

HWASan trong ứng dụng

Tương tự như AddressSanitizer, HWASan không thể xem mã Java, nhưng có thể phát hiện lỗi trong các thư viện JNI. Cho đến phiên bản Android 14, việc chạy các ứng dụng HWASan trên một thiết bị không phải HWASan không được hỗ trợ.

Trên thiết bị HWASan, các ứng dụng có thể được kiểm tra bằng HWASan bằng cách tạo mã của chúng bằng SANITIZE_TARGET:=hwaddress trong Make hoặc -fsanitize=hwaddress trong cờ trình biên dịch. Trên một thiết bị không phải HWASan (chạy Android 14 trở lên), bạn phải thêm chế độ cài đặt tệp wrap.sh LD_HWASAN=1. Hãy xem tài liệu dành cho nhà phát triển ứng dụng để biết thêm thông tin chi tiết.