{i>UndefinedBehaviorSanitizer <i}(UBSan) melakukan instrumentasi waktu kompilasi untuk memeriksa berbagai jenis perilaku yang tidak terdefinisi. Meskipun UBSan mampu mendeteksi banyak bug perilaku yang tidak ditentukan, Android mendukung:
- perataan
- Bool
- batas
- enum
- {i>float-cast-overflow<i}
- mengambang-bagi-dengan nol
- bilangan bulat-pembagian-dengan nol
- atribut bukan null
- null
- return
- atribut return-nonnull-
- shift-base
- eksponen shift
- tanda tangan bilangan bulat-overflow
- tidak dapat dijangkau
- tidak-bilangan bulat-overflow
- terikat vla
stateless-integer-overflow, sementara secara teknis tidak ditentukan aktif, tercakup dalam sanitizer dan digunakan di banyak modul Android, termasuk komponen server media, untuk menghilangkan integer-overflow laten kerentanan.
Implementasi
Dalam sistem build Android, Anda dapat mengaktifkan UBSan secara global atau lokal. Untuk mengaktifkan UBSan secara global, tetapkan SANITIZE_TARGET di Android.mk. Untuk mengaktifkan UBSan pada tingkat per modul, tetapkan LOCAL_SANITIZE dan tentukan perilaku yang tidak terdefinisi yang yang ingin Anda cari di Android.mk. Contoh:
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_CFLAGS := -std=c11 -Wall -Werror -O0 LOCAL_SRC_FILES:= sanitizer-status.c LOCAL_MODULE:= sanitizer-status LOCAL_SANITIZE := alignment bounds null unreachable integer LOCAL_SANITIZE_DIAG := alignment bounds null unreachable integer include $(BUILD_EXECUTABLE)
Dan konfigurasi blueprint yang setara (Android.bp):
cc_binary { cflags: [ "-std=c11", "-Wall", "-Werror", "-O0", ], srcs: ["sanitizer-status.c"], name: "sanitizer-status", sanitize: { misc_undefined: [ "alignment", "bounds", "null", "unreachable", "integer", ], diag: { misc_undefined: [ "alignment", "bounds", "null", "unreachable", "integer", ], }, }, }
Pintasan UBSan
Android juga memiliki dua pintasan, integer
dan
default-ub
, untuk mengaktifkan rangkaian pembersih tangan secara bersamaan. bilangan bulat
mengaktifkan integer-divide-by-zero
,
signed-integer-overflow
dan unsigned-integer-overflow
.
default-ub
mengaktifkan pemeriksaan yang memiliki compiler minimal
masalah performa: bool, integer-divide-by-zero, return,
returns-nonnull-attribute, shift-exponent, unreachable and vla-bound
. Tujuan
kelas pembersih integer dapat digunakan dengan SANITIZE_TARGET dan LOCAL_SANITIZE,
sedangkan default-ub hanya dapat digunakan dengan SANITIZE_TARGET.
Pelaporan error yang lebih baik
Implementasi UBSan default Android memanggil fungsi yang ditentukan saat ditemukan perilaku yang tidak terdefinisi. Secara default, fungsi ini dibatalkan. Namun, mulai Oktober 2016, UBSan di Android memiliki pustaka runtime opsional yang memberikan pelaporan error yang lebih mendetail, termasuk jenis perilaku yang tidak ditentukan ditemukan, file dan informasi baris kode sumber. Untuk mengaktifkan error ini pelaporan dengan pemeriksaan integer akan menambahkan kode berikut ke file Android.mk:
LOCAL_SANITIZE:=integer LOCAL_SANITIZE_DIAG:=integer
Nilai LOCAL_SANITIZE memungkinkan sanitizer selama build. LOCAL_SANITIZE_DIAG mengaktifkan mode diagnostik untuk pembersih yang ditentukan. Penting memungkinkan untuk menetapkan LOCAL_SANITIZE dan LOCAL_SANITIZE_DIAG ke nilai yang berbeda, tetapi hanya pemeriksaan tersebut di LOCAL_SANITIZE yang diaktifkan. Jika suatu pemeriksaan tidak ditentukan dalam LOCAL_SANITIZE, tetapi ditentukan dalam LOCAL_SANITIZE_DIAG, pemeriksaan ini tidak diaktifkan dan pesan diagnostik tidak diberikan.
Berikut ini contoh informasi yang disediakan oleh library runtime UBSan:
pixel-xl:/ # sanitizer-status ubsan sanitizer-status/sanitizer-status.c:53:6: runtime error: unsigned integer overflow: 18446744073709551615 + 1 cannot be represented in type 'size_t' (aka 'unsigned long')
Sanitasi bilangan bulat
Overflow bilangan bulat yang tidak diinginkan dapat menyebabkan kerusakan atau informasi memori kerentanan pengungkapan dalam variabel yang terkait dengan akses memori atau alokasi memori. Untuk mengatasi hal ini, kami menambahkan Clang UndefinedBehaviorSanitizer (UBSan) pembersih bilangan bulat yang bertanda tangan dan tidak ditandatangani untuk memperkeras framework media di Android 7.0. Pada Android 9, kita diperluas UBSan untuk mencakup lebih banyak komponen dan meningkatkan dukungan sistem build untuknya.
Ini dirancang untuk menambahkan pemeriksaan seputar aritmetika Operations / instructions—yang mungkin overflow—untuk membatalkan proses dengan aman jika terjadi overflow. Pembersih ini dapat mengurangi kerusakan seluruh kelas memori dan kerentanan pengungkapan informasi di mana penyebab utama adalah bilangan bulat tambahan, seperti kerentanan Stagefright asli.
Contoh dan sumber
{i>Integer Overflow Sanitization <i}(IntSan) disediakan oleh compiler dan menambahkan
instrumentasi ke dalam biner selama waktu kompilasi untuk mendeteksi aritmetika
tambahan. Diaktifkan secara default di berbagai komponen di seluruh
terkelola, misalnya
/platform/external/libnl/Android.bp
Implementasi
IntSan menggunakan sanitizer overflow bilangan bulat yang ditandatangani dan tidak ditandatangani dari UBSan. Ini mitigasi diaktifkan pada tingkat per modul. Hal ini membantu menjaga komponen penting Android aman dan tidak boleh dinonaktifkan.
Kami sangat menganjurkan Anda untuk mengaktifkan Sanitasi Luapan Bilangan Bulat sebagai komponen. Kandidat ideal adalah kode native atau kode native dengan hak istimewa yang mengurai input pengguna yang tidak tepercaya. Ada overhead performa kecil yang terkait dengan pembersih yang bergantung pada penggunaan kode dan prevalensi operasi aritmatika. Akan ada persentase {i>overhead<i} yang kecil dan uji apakah performa menjadi kekhawatiran.
Mendukung IntSan di makefile
Untuk mengaktifkan IntSan di makefile, tambahkan:
LOCAL_SANITIZE := integer_overflow # Optional features LOCAL_SANITIZE_DIAG := integer_overflow LOCAL_SANITIZE_BLOCKLIST := modulename_BLOCKLIST.txt
LOCAL_SANITIZE
mengambil daftar pembersih yang dipisahkan koma, denganinteger_overflow
berupa kumpulan opsi yang sudah dikemas sebelumnya untuk {i>overflow sanitizer<i} bilangan bulat yang ditandatangani dan tidak ditandatangani dengan bawaan BLOKIR.LOCAL_SANITIZE_DIAG
mengaktifkan mode diagnostik untuk pembersih. Gunakan mode diagnostik hanya selama pengujian karena mode ini tidak pembatalan pada {i>overflow<i}, sepenuhnya mengabaikan keuntungan keamanan dari mitigasi. Lihat Pemecahan masalah untuk detail tambahan.LOCAL_SANITIZE_BLOCKLIST
memungkinkan Anda menentukan BLOCKLIST untuk mencegah proses pembersihan fungsi dan file sumber. Lihat Pemecahan masalah untuk informasi tambahan spesifikasi pendukung.
Jika Anda menginginkan kontrol yang lebih terperinci, aktifkan pembersih satu per satu menggunakan satu atau kedua tanda:
LOCAL_SANITIZE := signed-integer-overflow, unsigned-integer-overflow LOCAL_SANITIZE_DIAG := signed-integer-overflow, unsigned-integer-overflow
Mendukung IntSan dalam file blueprint
Untuk mengaktifkan sanitasi tambahan bilangan bulat dalam file blueprint, seperti
/platform/external/libnl/Android.bp
,
tambahkan:
sanitize: { integer_overflow: true, diag: { integer_overflow: true, }, BLOCKLIST: "modulename_BLOCKLIST.txt", },
Seperti halnya file make, properti integer_overflow
merupakan paket
sekumpulan opsi untuk luapan bilangan bulat individual yang ditandatangani dan tidak ditandatangani
pembersih dengan default
BLOKIR.
Rangkaian properti diag
memungkinkan mode diagnostik untuk
pembersih. Gunakan mode diagnostik hanya selama pengujian. Mode diagnostik tidak
batalkan pada overflow, yang sepenuhnya
mengabaikan keuntungan keamanan dari
mitigasi dalam build pengguna. Lihat Pemecahan masalah untuk detail selengkapnya.
Properti BLOCKLIST
mengizinkan spesifikasi file BLOCKLIST
yang memungkinkan developer mencegah fungsi dan file sumber ditampilkan
dibersihkan. Lihat Pemecahan masalah untuk
detail tambahan.
Untuk mengaktifkan cairan pembersih satu per satu, gunakan:
sanitize: { misc_undefined: ["signed-integer-overflow", "unsigned-integer-overflow"], diag: { misc_undefined: ["signed-integer-overflow", "unsigned-integer-overflow",], }, BLOCKLIST: "modulename_BLOCKLIST.txt", },
Pemecahan masalah
Jika Anda mengaktifkan sanitasi tambahan bilangan bulat dalam komponen baru, atau mengandalkan library platform yang telah memiliki sanitasi tambahan bilangan bulat, Anda mungkin akan beberapa masalah dengan overflow bilangan bulat jinak yang menyebabkan pembatalan. Anda harus menguji dengan sanitasi diaktifkan untuk memastikan luapan yang tidak berbahaya dapat muncul.
Untuk menemukan, pembatalan yang disebabkan oleh sanitasi di build pengguna, telusuri
SIGABRT
error dengan pesan Batalkan yang menunjukkan bahwa kelebihan beban terdeteksi
oleh UBSan, seperti:
pid: ###, tid: ###, name: Binder:### >>> /system/bin/surfaceflinger <<< signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr -------- Abort message: 'ubsan: sub-overflow'
Stack trace harus menyertakan fungsi yang menyebabkan pembatalan, kelebihan yang terjadi dalam fungsi inline mungkin tidak terlihat dalam pelacakan tumpukan.
Agar lebih mudah menentukan akar masalah, aktifkan diagnostik di library memicu pembatalan dan mencoba mereproduksi {i>error<i}. Dengan diagnostik diaktifkan, proses tidak akan dibatalkan dan sebagai gantinya terus berjalan. Tidak membatalkan akan membantu memaksimalkan jumlah luapan yang tidak berbahaya dalam jalur eksekusi tertentu tanpa harus mengompilasi ulang setelah memperbaiki setiap {i>bug<i}. Diagnostik menghasilkan pesan error yang menyertakan nomor baris dan sumber yang menyebabkan pembatalan:
frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp:2188:32: runtime error: unsigned integer overflow: 0 - 1 cannot be represented in type 'size_t' (aka 'unsigned long')
Setelah operasi aritmatika yang bermasalah ditemukan, pastikan bahwa menu tambahan tidak berbahaya dan dimaksudkan (misalnya, tidak memiliki implikasi keamanan). Anda dapat mengatasi pembatalan melalui cairan pembersih oleh:
- Memfaktorkan ulang kode untuk menghindari overflow (contoh)
- Overflow secara eksplisit melalui __builtin_*_overflow Clang fungsi (contoh)
- Menonaktifkan sanitasi dalam fungsi dengan menentukan atribut
no_sanitize
(contoh) - Menonaktifkan sanitasi fungsi atau file sumber melalui file BLOCKLIST (contoh)
Anda harus menggunakan solusi yang paling terperinci. Misalnya, fungsi dengan banyak operasi aritmatika dan satu operasi overflow harus memfaktorkan ulang operasi tunggal, bukan seluruh fungsi DIBLOKIR.
Pola umum yang dapat menyebabkan overflow tidak berbahaya meliputi:
- Implisit transmisi jika terjadi overflow yang tidak ditandatangani sebelum ditransmisikan ke jenis yang ditandatangani (contoh)
- Penghapusan daftar tertaut yang mengurangi indeks loop saat penghapusan (contoh)
- Menetapkan jenis yang tidak ditandatangani ke -1, bukan menentukan nilai maksimum yang sebenarnya (contoh)
- Loop yang mengurangi bilangan bulat tanpa tanda tangan dalam kondisi (contoh, contoh)
Sebaiknya developer memastikan bahwa kasus di mana cairan pembersih mendeteksi kelebihan bahwa variabel ini memang tidak berbahaya tanpa efek samping atau keamanan yang tidak diinginkan implikasi sebelum menonaktifkan sanitasi.
Nonaktifkan IntSan
Anda dapat menonaktifkan IntSan dengan BLOCKLIST atau atribut fungsi. Nonaktifkan seperlunya dan hanya ketika memfaktorkan ulang kode yang tidak wajar atau jika ada {i>overhead<i} kinerja yang bermasalah.
Lihat dokumentasi Clang upstream untuk informasi selengkapnya tentang cara menonaktifkan IntSan dengan fungsi atribut dan file BLOCKLIST format. BLOCKLISTing harus dicakupkan ke pembersih tertentu dengan menggunakan nama bagian yang menentukan pembersih target agar tidak berdampak pada pembersih.
Validasi
Saat ini, tidak ada uji CTS khusus untuk Sanitasi Tambahan Bilangan Bulat. Sebaliknya, pastikan bahwa uji CTS lulus dengan atau tanpa mengaktifkan IntSan untuk bahwa hal itu tidak mempengaruhi perangkat.
Sanitasi batas
BoundsSanitizer (BoundSan) menambahkan instrumentasi ke biner untuk menyisipkan batas terkait akses array. Pemeriksaan ini ditambahkan jika compiler tidak membuktikan pada waktu kompilasi bahwa aksesnya akan aman dan jika ukuran array akan diketahui saat runtime, sehingga dapat diperiksa. Android 10 men-deploy BoundSan di Bluetooth dan codec. BoundSan disediakan oleh compiler dan diaktifkan oleh {i>default<i} di berbagai komponen di seluruh platform.
Implementasi
BoundSan menggunakan UBSan membatasi {i>sanitizer<i}. Mitigasi ini diaktifkan pada tingkat per modul. Membantu menjaga komponen penting Android tetap aman dan tidak boleh dinonaktifkan.
Sebaiknya Anda mengaktifkan BoundSan untuk komponen tambahan. Kandidat ideal adalah kode native dengan hak istimewa atau kode native kompleks yang mengurai input pengguna yang tidak tepercaya. Overhead performa yang terkait dengan pengaktifan BoundSan tergantung pada jumlah akses {i>array<i} yang tidak dapat dibuktikan aman. Dapatkan persentase {i>overhead<i} yang kecil rata-rata dan menguji apakah kinerja menjadi perhatian.
Mengaktifkan BoundSan dalam file blueprint
BoundSan dapat diaktifkan di file blueprint dengan menambahkan "bounds"
ke properti sanitasi misc_undefined
untuk biner dan library
modul:
sanitize: { misc_undefined: ["bounds"], diag: { misc_undefined: ["bounds"], }, BLOCKLIST: "modulename_BLOCKLIST.txt",
diag
Properti diag
mengaktifkan mode diagnostik untuk pembersih.
Gunakan mode diagnostik hanya selama pengujian. Mode diagnostik tidak dibatalkan pada
kelebihan beban, yang meniadakan manfaat keamanan dari mitigasi dan membawa
overhead performa yang lebih tinggi, sehingga tidak direkomendasikan untuk build produksi.
DAFTAR BLOKIR
Properti BLOCKLIST
mengizinkan spesifikasi BLOCKLIST
yang dapat digunakan developer untuk mencegah fungsi dan file sumber ditampilkan
dibersihkan. Gunakan properti ini hanya jika performa menjadi perhatian Anda dan yang ditargetkan
file/fungsi berkontribusi secara substansial. Audit file/fungsi ini secara manual
untuk memastikan keamanan
akses {i>array<i}. Lihat Pemecahan masalah untuk informasi lainnya
spesifikasi
pendukung.
Mengaktifkan BoundSan di makefile
BoundSan dapat diaktifkan di makefile dengan menambahkan "bounds"
ke variabel LOCAL_SANITIZE
untuk modul biner dan library:
LOCAL_SANITIZE := bounds # Optional features LOCAL_SANITIZE_DIAG := bounds LOCAL_SANITIZE_BLOCKLIST := modulename_BLOCKLIST.txt
LOCAL_SANITIZE
menerima daftar pembersih yang dipisahkan oleh
koma.
LOCAL_SANITIZE_DIAG
mengaktifkan mode diagnostik. Gunakan diagnostik
mode hanya selama pengujian. Mode diagnostik tidak dibatalkan saat terjadi overflow, yang
meniadakan manfaat keamanan dari mitigasi dan memiliki dampak yang
overhead performa, jadi tidak disarankan untuk build produksi.
LOCAL_SANITIZE_BLOCKLIST
mengizinkan spesifikasi BLOCKLIST
file yang memungkinkan developer mencegah fungsi dan file sumber ditampilkan
dibersihkan. Gunakan properti ini hanya jika performa menjadi perhatian Anda dan yang ditargetkan
file/fungsi berkontribusi secara substansial. Audit file/fungsi ini secara manual
untuk memastikan keamanan
akses {i>array<i}. Lihat Pemecahan masalah untuk informasi lainnya
spesifikasi
pendukung.
Nonaktifkan BoundSan
Anda dapat menonaktifkan BoundSan di fungsi dan file sumber dengan BLOCKLIST atau fungsi. Sebaiknya tetap aktifkan BoundSan, jadi hanya nonaktifkan jika fungsi atau file menimbulkan {i>overhead<i} kinerja dalam jumlah besar dan sumber telah ditinjau secara manual.
Untuk Informasi selengkapnya tentang cara menonaktifkan BoundSan dengan function atribut dan file BLOCKLIST format, lihat dokumentasi Clang LLVM. Membuat ruang lingkup BLOKIR ke sanitizer tertentu dengan menggunakan nama bagian yang menentukan target sanitizer agar tidak berdampak pada cairan pembersih lainnya.
Validasi
Tidak ada uji CTS khusus untuk BoundSan. Sebaliknya, pastikan bahwa CTS pengujian lulus dengan atau tanpa mengaktifkan BoundSan untuk memverifikasi bahwa pengujian tersebut tidak memengaruhi perangkat.
Pemecahan masalah
Uji komponen secara menyeluruh setelah mengaktifkan BoundSan untuk memastikan bahwa akses di luar batas yang tidak terdeteksi akan ditangani.
Error BoundSan dapat dengan mudah diidentifikasi karena mencakup hal berikut pesan pembatalan tombstone:
pid: ###, tid: ###, name: Binder:### >>> /system/bin/foobar <<< signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr -------- Abort message: 'ubsan: out-of-bounds'
Saat dijalankan dalam mode diagnostik, file sumber, nomor baris, dan indeks
nilai dicetak ke logcat
. Secara {i>default<i},
mode ini tidak
menampilkan pesan batalkan. Tinjau logcat
untuk memeriksa apakah ada
yang sama.
external/foo/bar.c:293:13: runtime error: index -1 out of bounds for type 'int [24]'