Các phần mã có thể thực thi cho tệp nhị phân hệ thống AArch64 được đánh dấu theo mặc định chỉ thực thi (không đọc được) như một biện pháp giảm thiểu tăng cường chống lại mã đúng thời điểm sử dụng lại các cuộc tấn công. Loại mã kết hợp dữ liệu và mã với nhau rồi mã có chủ đích kiểm tra những phần này (mà không cần ánh xạ lại các phân đoạn bộ nhớ trước là có thể đọc được) không còn hoạt động nữa. Ứng dụng có SDK mục tiêu là 10 (API cấp 29 trở lên) sẽ bị ảnh hưởng nếu ứng dụng cố gắng đọc các phần mã của Thư viện hệ thống hỗ trợ bộ nhớ chỉ thực thi (XOM) trong bộ nhớ không có trước đánh dấu phần này là có thể đọc được.
Để hưởng lợi tối đa từ giải pháp giảm thiểu này, cả khả năng hỗ trợ cả phần cứng và nhân hệ điều hành đều: là bắt buộc. Nếu không có sự hỗ trợ này, biện pháp giảm thiểu có thể chỉ được thực thi một phần. Chiến lược phát hành đĩa đơn Nhân hệ điều hành phổ biến của Android 4.9 chứa các bản vá thích hợp để cung cấp đầy đủ khả năng hỗ trợ cho quy trình này trên các thiết bị ARMv8.2.
Triển khai
Các tệp nhị phân AArch64 do trình biên dịch tạo giả định rằng mã và dữ liệu kết hợp. Việc bật tính năng này không ảnh hưởng tiêu cực đến hiệu suất của thiết bị.
Đối với đoạn mã phải chủ ý xem xét bộ nhớ trên
phân đoạn có thể thực thi, bạn nên gọi mprotect
trên
các đoạn mã cần kiểm tra để đảm bảo chúng dễ đọc, sau đó
sẽ xoá khả năng đọc khi quá trình kiểm tra hoàn tất.
Phương thức triển khai này dẫn đến việc đọc các phân đoạn bộ nhớ được đánh dấu là
chỉ thực thi để dẫn đến lỗi phân đoạn (SEGFAULT
).
Điều này có thể xảy ra do lỗi, lỗ hổng bảo mật, dữ liệu kết hợp với
mã (phân tách theo nghĩa đen) hoặc chủ ý xem xét bộ nhớ.
Mức độ hỗ trợ và tác động đối với thiết bị
Thiết bị có phần cứng cũ hơn hoặc các nhân phiên bản cũ hơn (thấp hơn 4.9) mà không có
các bản vá cần thiết có thể không hỗ trợ đầy đủ hoặc hưởng lợi từ tính năng này. Thiết bị
không có hỗ trợ nhân hệ điều hành có thể không thực thi quyền truy cập của người dùng vào bộ nhớ chỉ thực thi,
tuy nhiên, mã hạt nhân kiểm tra rõ ràng xem một trang có thể đọc được hay không
thực thi thuộc tính này, chẳng hạn như process_vm_readv()
.
Cờ nhân CONFIG_ARM64_UAO
phải được đặt trong nhân thành
đảm bảo rằng hạt nhân tuân thủ các trang miền người dùng được đánh dấu là chỉ thực thi. ARMv8 cũ hơn
hoặc các thiết bị ARMv8.2 đã tắt tính năng Ghi đè quyền truy cập của người dùng (UAO) có thể không
khai thác tối đa tính năng này và vẫn có thể đọc các trang chỉ thực thi bằng cách sử dụng
gọi hệ thống.
Tái cấu trúc mã hiện có
Mã được chuyển từ AArch32 có thể chứa dữ liệu hỗn hợp và
khiến phát sinh vấn đề. Trong nhiều trường hợp, việc khắc phục những vấn đề này rất đơn giản
khi di chuyển các hằng số sang phần .data
trong tệp tập hợp.
Cấu trúc viết tay có thể cần được tái cấu trúc để tách riêng các tập hợp được gộp cục bộ hằng số.
Ví dụ:
Tệp nhị phân do trình biên dịch Clang tạo ra sẽ không gặp vấn đề gì với dữ liệu được kết hợp trong mã. Nếu mã do bộ sưu tập trình biên dịch GNU (GCC) tạo là được đưa vào (từ một thư viện tĩnh), kiểm tra tệp nhị phân đầu ra để đảm bảo rằng các hằng số không được gộp vào các phần mã.
Nếu cần phải xem xét mã trên các phần mã có thể thực thi,
đầu tiên, hãy gọi mprotect
để đánh dấu mã có thể đọc được. Sau đó, sau thao tác
đã hoàn tất, hãy gọi lại mprotect
để đánh dấu là không đọc được.
Bật XOM
Chế độ chỉ thực thi được bật theo mặc định cho tất cả tệp nhị phân 64 bit trong bản dựng hệ thống.
Tắt XOM
Bạn có thể tắt chế độ chỉ thực thi ở cấp mô-đun, theo toàn bộ cây thư mục con, hoặc cho toàn bộ bản dựng.
Bạn có thể tắt XOM cho từng mô-đun riêng lẻ không tái cấu trúc được hoặc cần đọc các mô-đun đó
mã thực thi bằng cách đặt giá trị LOCAL_XOM
và xom
thành false
.
// Android.mk LOCAL_XOM := false // Android.bp cc_binary { // or other module types ... xom: false, }
Nếu bộ nhớ chỉ thực thi bị tắt trong thư viện tĩnh, hệ thống xây dựng sẽ áp dụng
cho tất cả các mô-đun phụ thuộc của thư viện tĩnh đó. Bạn có thể ghi đè
điều này bằng cách sử dụng xom: true,
.
Để vô hiệu hoá bộ nhớ chỉ thực thi trong một thư mục con cụ thể (ví dụ:
foo/bar/), hãy chuyển giá trị đến XOM_EXCLUDE_PATHS
.
make -j XOM_EXCLUDE_PATHS=foo/bar
Ngoài ra, bạn có thể đặt PRODUCT_XOM_EXCLUDE_PATHS
trong cấu hình sản phẩm của bạn.
Bạn có thể vô hiệu hoá các tệp nhị phân chỉ thực thi trên toàn cục bằng cách truyền
ENABLE_XOM=false
vào lệnh make
.
make -j ENABLE_XOM=false
Xác nhận kết quả
Không có chương trình kiểm thử xác minh hoặc CTS nào dành cho chỉ thực thi
bộ nhớ. Bạn có thể xác minh tệp nhị phân theo cách thủ công bằng readelf
và kiểm tra
cờ phân đoạn.