Xem Tìm hiểu các báo cáo HWASan để biết thông tin về cách đọc các sự cố HWASan!
AddressSanitizer được hỗ trợ bởi phần cứng (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 rất nhiều so với ASan, điều này khiến nó phù hợp cho việc vệ sinh toàn bộ hệ thống. HWASan chỉ khả dụng trên Android 10 trở lên và chỉ 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 gây ra sự cố trong C/C++ được sử dụng để triển khai các giao diện Java. Nó hữu ích vì nó phát hiện các lỗi bộ nhớ khi chúng xảy ra, chỉ cho bạn trực tiếp mã chịu trách nhiệm.
Bạn có thể flash các hình ảnh HWASan dựng sẵn vào 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ổ điển, HWASan có:
- Chi phí CPU tương tự (~2x)
- Chi phí kích thước mã tương tự (40 – 50%)
- Chi phí RAM nhỏ hơn nhiều (10% – 35%)
HWASan phát hiện cùng một nhóm lỗi như ASan:
- Tràn/tràn bộ đệm ngăn xếp và bộ nhớ heap
- Heap sử dụng sau khi miễn phí
- Ngăn xếp sử dụng bên ngoài phạm vi
- Miễn phí gấp đôi / miễn phí hoang dã
Ngoài ra, HWASan 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 có thể được kích hoạt trên một mục tiêu cùng một lúc.
Chi tiết triển khai và giới hạn
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 bộ nhớ hợp lệ, con trỏ và thẻ bộ nhớ phải khớp. HWASan dựa vào tính năng bỏ qua byte trên cùng (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 web tài liệu Clang.
Theo thiết kế, HWASan không có vùng đỏ kích thước giới hạn của ASan để phát hiện tràn hoặc cách ly dung lượng giới hạn của ASan để phát hiện việc sử dụng sau khi miễn phí. Vì lý do này, HWASan có thể phát hiện lỗi bất kể mức độ tràn lớn như thế nào hoặc bộ nhớ đã được giải phóng cách đây 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ể có (256), có nghĩa là có 0,4% xác suất bỏ sót bất kỳ lỗi nào trong một lần thực hiện chương trình.
Yêu cầu
Các phiên bản gần đây (4.14+) của nhân Android phổ biến hỗ trợ HWASan ngay khi xuất xưởng. Các nhánh cụ thể của Android 10 không hỗ trợ HWASan.
Hỗ trợ không gian người dùng cho HWASan khả dụng kể từ Android 11 .
Nếu bạn đ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 các con trỏ được gắn thẻ trong các đối số lệnh gọi hệ thống. Hỗ trợ cho điều này đã được triển khai trong các bản vá ngược dòng sau:
- địa chỉ được gắn thẻ arm64 ABI
- arm64: bỏ gắn thẻ con trỏ người dùng được truyền tới kernel
- mm: Tránh tạo bí danh địa chỉ ả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ừ các luồng nhân
Nếu bạn đang xây dựng với một chuỗi công cụ tùy chỉnh, hãy đảm bảo rằng nó bao gồm mọi thứ cho đến LLVM commit 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ự như aosp_coral_hwasan .
Đối với những người dùng quen thuộc với AddressSanitizer, rất nhiều sự phức tạp trong quá trình xây dựng đã biến mất:
- 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 flash dữ liệu người dùng.
Một số hạn chế của AddressSanitizer cũng không còn nữa:
- Thực thi tĩnh được hỗ trợ.
- Bạn có thể bỏ qua việc vệ sinh bất kỳ mục tiêu nào ngoài libc. Không giống như ASan, không có yêu cầu rằng nếu một thư viện được làm sạch, thì bất kỳ tệp thực thi nào liên kết với nó cũng phải như vậy.
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) có thể được thực hiện tự do. Lau thiết bị là không cần thiết.
Để bỏ qua quy trình vệ sinh mô-đun, hãy sử dụng LOCAL_NOSANITIZE := hwaddress
(Android.mk) hoặc sanitize: { hwaddress: false }
(Android.bp).
Vệ sinh các mục tiêu cá nhâ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 vệ sinh), miễn là libc.so
cũng được vệ sinh. Thêm hwaddress: true
vào khối vệ sinh trong "libc_defaults"
trong bionic/libc/Android.bp. Sau đó, làm tương tự trong mục tiêu bạn đang làm việc.
Lưu ý rằng việc khử trùng libc cho phép gắn thẻ phân bổ bộ nhớ heap trên toàn hệ thống, cũng như kiểm tra các thẻ cho hoạt động của bộ nhớ bên trong libc.so
. Điều này có thể bắt lỗi ngay cả trong các tệp nhị phân mà HWASan không được bật nếu quyền truy cập bộ nhớ kém nằm trong libc.so
(ví dụ: pthread_mutex_unlock()
trên một mutex delete()
ed).
Không cần thiết phải 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.
Flashstation
Vì mục đích phát triển, bạn có thể flash bản dựng AOSP hỗ trợ HWASan vào thiết bị Pixel có bộ tải khởi động đã mở khóa bằng Flashstation . Chọn mục tiêu _hwasan, ví dụ: aosp_flame_hwasan-userdebug. Xem tài liệu NDK về 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 tốt hơn
HWASan sử dụng một trình giải phóng 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 cấp phát và hủy cấp phát bộ nhớ trong chương trình. Theo mặc định, Android cho phép con trỏ khung trong mã AArch64, vì vậy điều này hoạt động tốt trong thực tế. Nếu bạn cần thư giãn 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. Lưu ý rằng các dấu vết ngăn xếp truy cập bộ nhớ kém sử dụng trình giải nén "chậm" theo mặc định; cài đặt này chỉ ảnh hưởng đến dấu vết phân bổ và thỏa thuận. Tùy chọn này có thể rất tốn CPU, tùy thuộc vào tải.
tượng trưng
Xem Biểu tượng hóa trong "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 nó có thể phát hiện lỗi trong thư viện JNI. Cho đến Android 14, việc chạy ứng dụng HWASan trên thiết bị không phải HWASan không được hỗ trợ.
Trên thiết bị HWASan, có thể kiểm tra các ứng dụng bằng HWASan bằng cách xây dựng mã của chúng với SANITIZE_TARGET:=hwaddress
trong Make hoặc -fsanitize=hwaddress
trong cờ trình biên dịch. Trên thiết bị không phải HWASan (chạy Android 14 trở lên), phải thêm cài đặt tệp wrap.sh 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.