Xem bài viết Tìm hiểu về HWASan báo cáo để biết thông tin về cách đọc sự cố HWASan!
AddressSanitizer (HWASan) có sự hỗ trợ của phần cứng là một lỗi bộ nhớ công cụ phát hiện tương tự như AddressSanitizer. HWASan sử dụng ít RAM hơn nhiều so với ASan, điều này phù hợp với 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++, HWASan cũng có thể giúp gỡ lỗi mã Java khiến sự cố trong C/C++ dùng để triển khai giao diện Java. Việc này hữu ích vì giúp thu hút bộ nhớ lỗi khi chúng xảy ra, trực tiếp hướng bạn đến mã chịu trách nhiệm.
Bạn có thể truyền nhanh hình ảnh HWASan tạo sẵn sang các thiết bị Pixel được hỗ trợ từ ci.android.com (hướng dẫn thiết lập chi tiết).
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 nhỏ 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 phát hiện việc sử dụng ngăn xếp sau khi trả về.
HWASan (tương tự như ASan) tương thích với UBSan, có thể bật cả hai trên một mục tiêu cùng một lúc.
Thông tin chi tiết và giới hạn về việc triển khai
HWASan dựa trên bộ nhớ phương pháp gắn thẻ, trong đó một giá trị thẻ ngẫu nhiên nhỏ được liên kết cả với con trỏ và dải địa chỉ bộ nhớ. Để tạo kỷ niệm mới hợp lệ, con trỏ và thẻ nhớ phải khớp nhau. HWASan dựa vào bỏ qua byte trên cùng của tính năng ARMv8 (TBI), còn được gọi là gắn thẻ địa chỉ ảo để lưu trữ thẻ con trỏ trong 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 web tài liệu về Clang.
Theo thiết kế, HWASan không có các vùng đỏ có kích thước giới hạn của ASan đối với phát hiện lỗi tràn hoặc vùng cách ly dung lượng giới hạn của ASan đối với phát hiện 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ể phần bị tràn có kích thước lớn đến mức nào hoặc bộ nhớ đó cách đây bao lâu đã được giải quyết. Đ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ó số lượng giá trị thẻ giới hạn (256), có nghĩa là xác suất bỏ lỡ bất kỳ lỗi nào là 0,4% trong một lần chạy chương trình.
Yêu cầu
Phiên bản gần đây (4.14 trở lên) của hỗ trợ nhân hệ điều hành Android phổ biến HWASan ngay từ đầu. Các nhánh cụ thể trên Android 10 không hỗ trợ HWASan.
Tính năng hỗ trợ không gian người dùng dành cho HWASan hiện có từ Android 11.
Nếu bạn đang làm việc với một nhân hệ điều hành khác, HWASan yêu cầu nhân hệ điều hành Linux phải chấp nhận con trỏ được gắn thẻ trong đố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ộ bản vá ngược dòng (upstream):
- địa chỉ ABI được gắn thẻ arm64
- arm64: huỷ gắn thẻ con trỏ của người dùng được chuyển đến nhân hệ điều hành
- mm: Tránh tạo email đại diện ảo trong brk()/mmap()/mremap()
- arm64: Xác thực các địa chỉ được gắn thẻ trong access_ok() được gọi từ luồng nhân hệ điều hành
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ụ đó có đủ mọi thành phần theo cam kết LLVM c336557f.
Sử dụng HWASan
Sử dụng các lệnh sau để xây dựng 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 cài đặt SANITIZE_TARGET vào định nghĩa sản phẩm, tương tự với aosp_coral_hwasan.
Đối với những người dùng quen thuộc với AddressSanitizer, rất nhiều việc xây dựng phức tạp đã không còn nữa:
- Không cần chạy make hai lần.
- Các bản dựng gia tăng hoạt động tốt.
- Không cần cài đặt ROM dữ liệu người dùng.
Một số hạn chế của AddressSanitizer cũng sẽ biến mất:
- Hỗ trợ các tệp thực thi tĩnh.
- Bạn có thể bỏ qua bước dọn dẹp bất kỳ mục tiêu nào không phải libc. Không giống như ASan, có không bắt buộc rằng 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 vậy.
Bạn có thể chuyển đổi giữa HWASan và các hình ảnh thông thường ở cùng số bản dựng (hoặc cao hơn) được thực hiện một cách tự do. Không cần phải xoá thiết bị.
Để bỏ qua bước dọn dẹp 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 dọn dẹp trong "libc_defaults"
trong bionic/libc/Android.bp. Sau đó, làm tương tự với mục tiêu bạn đang thực hiện.
Lưu ý rằng tính năng dọn dẹp libc cho phép gắn thẻ phân bổ bộ nhớ vùng nhớ khối xếp trên toàn hệ thống, cũng như
kiểm tra các thẻ cho hoạt động bộ nhớ bên trong libc.so
. Chế độ này có thể gặp lỗi ngay cả trong tệp nhị phân
HWASan không được bật nếu quyền truy cập không hợp lệ vào bộ nhớ nằm trong libc.so
(ví dụ: pthread_mutex_unlock()
trên một mutex 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 xây dựng bằng HWASan.
Bộ nhớ flash
Đối với mục đích phát triển, bạn có thể cài đặt ROM bản dựng AOSP hỗ trợ HWASan lên thiết bị Pixel có trình tải khởi động đã mở khoá bằng Flashstation. Chọn mục tiêu _hwasan, ví dụ: aosp_flame_hwasan-userdebug. Xem Tài liệu về NDK dành cho HWASan dành cho nhà phát triển ứng dụng để biết thêm chi tiết.
Dấu vết ngăn xếp chính xác hơn
HWASan sử dụng bộ tháo dỡ (unwinder) nhanh dựa trên con trỏ khung để ghi lại một ngăn xếp
theo dõi mọi sự kiện phân bổ và giải phóng bộ nhớ trong
. Theo mặc định, Android bật con trỏ khung trong mã AArch64,
để điều này mang lại hiệu quả
trong thực tế. Nếu bạn cần thư giãn
mã được quản lý, đặt HWASAN_OPTIONS=fast_unwind_on_malloc=0
trong môi trường tiến trình. Lưu ý rằng ngăn xếp truy cập bộ nhớ không hợp lệ
dấu vết sử dụng "chậm" gỡ bỏ theo mặc định; cài đặt này chỉ ảnh hưởng đến
dấu vết phân bổ và giải phóng. Lựa chọn này có thể rất
Tốn CPU, tuỳ thuộc vào tải.
Biểu tượng
Xem phần Biểu tượng hoá trong phần "Tìm hiểu báo cáo HWASan".
HWASan trong ứng dụng
Tương tự như AddressSanitizer, HWASan không thể nhìn thấy mã Java, nhưng nó có thể phát hiện lỗi trong thư viện JNI. Cho đến Android 14, việc chạy HWASan các ứng dụng trên thiết bị không phải là HWASan không được hỗ trợ.
Trên thiết bị HWASan, bạn có thể kiểm tra ứng dụng qua HWASan bằng cách tạo
mã có SANITIZE_TARGET:=hwaddress
inch
Tạo hoặc -fsanitize=hwaddress
trong cờ của trình biên dịch.
Trên thiết bị không dùng HWASan (chạy Android 14 trở lên), chế độ cài đặt tệp wrap.sh
Bạn phải thêm LD_HWASAN=1
.
Xem
tài liệu dành cho nhà phát triển ứng dụng
để biết thêm chi tiết.