ShadowCallStack (SCS) adalah mode instrumentasi LLVM yang melindungi terhadap penulisan ulang alamat return (seperti overflow buffer stack) dengan menyimpan alamat return fungsi ke ShadowCallStack yang dialokasikan secara terpisah di prolog fungsi dari fungsi non-leaf dan memuat alamat return dari ShadowCallStack di epilog fungsi. Alamat return juga disimpan di stack reguler untuk kompatibilitas dengan unwinder, tetapi tidak digunakan. Hal ini memastikan bahwa serangan yang memodifikasi alamat return pada stack reguler tidak berpengaruh pada alur kontrol program.
Di aarch64, instrumentasi menggunakan register x18
untuk mereferensikan ShadowCallStack, yang berarti bahwa referensi
ke ShadowCallStack tidak harus disimpan dalam memori.
Hal ini memungkinkan penerapan runtime yang menghindari eksposur
alamat ShadowCallStack kepada penyerang yang dapat membaca
memori arbitrer.
Implementasi
Android mendukung ShadowCallStack untuk kernel dan ruang pengguna.
Mengaktifkan SCS untuk kernel
Untuk mengaktifkan ShadowCallStack untuk kernel, tambahkan baris berikut ke file konfigurasi kernel:
CONFIG_SHADOW_CALL_STACK=y
Mengaktifkan SCS di ruang pengguna
Untuk mengaktifkan ShadowCallStack di komponen ruang pengguna, tambahkan baris berikut ke file blueprint komponen:
sanitize: { scs: true }
SCS mengasumsikan bahwa register x18
dicadangkan untuk menyimpan alamat
ShadowCallStack, dan tidak digunakan untuk tujuan lain apa pun. Meskipun semua library
sistem dikompilasi untuk mencadangkan register x18
, hal ini berpotensi
bermasalah jika SCS diaktifkan untuk komponen ruang pengguna yang berinteraksi dengan
kode lama dalam proses (misalnya, library yang dapat dimuat oleh aplikasi
pihak ketiga), yang dapat menghapus register x18
. Oleh karena itu, sebaiknya
aktifkan SCS dalam komponen mandiri yang tidak akan dimuat ke biner
lama.
Validasi
Tidak ada pengujian CTS khusus untuk SCS. Sebagai gantinya, pastikan pengujian CTS lulus dengan dan tanpa SCS diaktifkan untuk memverifikasi bahwa SCS tidak memengaruhi perangkat.