ShadowCallStack (SCS) là chế độ đo lường LLVM giúp chống lại địa chỉ trả về sẽ bị ghi đè (như tràn vùng đệm ngăn xếp) bằng cách lưu trả về địa chỉ ShadowCallStack được phân bổ riêng trong prolog hàm của các hàm không có lá và tải địa chỉ trả về từ ShadowCallStack trong phần tóm tắt về hàm. Địa chỉ trả lại hàng cũng được lưu trữ trên ngăn xếp thông thường để tương thích với bộ gỡ bỏ, nhưng không được sử dụng. Việc này đảm bảo rằng các cuộc tấn công sửa đổi địa chỉ trả về trong ngăn xếp thông thường đều không ảnh hưởng đến quy trình kiểm soát chương trình.
Trên Aarch64, khả năng đo lường sử dụng x18
đăng ký tham chiếu ShadowCallStack, nghĩa là tham chiếu
vào ShadowCallStack không cần được lưu trữ trong bộ nhớ.
Nhờ đó, bạn có thể triển khai một môi trường thời gian chạy mà tránh để lộ thông tin
địa chỉ của ShadowCallStack đối với những kẻ tấn công có thể đọc
bộ nhớ tuỳ ý.
Triển khai
Android hỗ trợ ShadowCallStack cho cả nhân hệ điều hành và không gian người dùng.
Bật SCS cho nhân
Để bật ShadowCallStack cho nhân, hãy thêm dòng sau vào lệnh tệp cấu hình kernel:
CONFIG_SHADOW_CALL_STACK=y
Bật SCS trong không gian người dùng
Để bật ShadowCallStack trong các thành phần không gian người dùng, hãy thêm các dòng sau vào tệp bản thiết kế của một thành phần:
sanitize: { scs: true }
SCS giả định rằng thanh ghi x18
được dành riêng để lưu trữ địa chỉ của
ShadowCallStack và không được sử dụng cho bất kỳ mục đích nào khác. Trong khi tất cả hệ thống
các thư viện được biên dịch để dự trữ thanh ghi x18
, điều này có thể xảy ra
gặp vấn đề nếu SCS được bật cho các thành phần không gian người dùng tương tác với
mã cũ trong quá trình xử lý (ví dụ: các thư viện có thể được tải bởi bên thứ ba
tạm thời) và điều này có thể sao chép thanh ghi x18
. Do đó, bạn chỉ nên
bật SCS trong các thành phần độc lập sẽ không được tải vào phiên bản cũ
tệp nhị phân.
Xác nhận kết quả
Không có thử nghiệm CTS nào dành riêng cho SCS. Thay vào đó, hãy đảm bảo rằng CTS kiểm thử truyền khi có và không bật SCS để xác minh rằng SCS không ảnh hưởng đến thiết bị.