Sanitasi Luapan Bilangan Bulat

Integer overflows yang tidak diinginkan dapat menyebabkan kerusakan memori atau kerentanan pengungkapan informasi dalam variabel yang terkait dengan akses memori atau alokasi memori. Untuk mengatasi hal ini, kami menambahkan Clang's UndefinedBehaviorSanitizer (UBSan) bertanda tangan dan tidak bertanda integer overflow sanitizer untuk memperkuat kerangka kerja media di Android 7.0. Di Android 9, kami memperluas UBSan untuk mencakup lebih banyak komponen dan meningkatkan dukungan sistem build untuknya.

Ini dirancang untuk menambahkan pemeriksaan di sekitar operasi/instruksi aritmatika—yang mungkin meluap—untuk membatalkan proses dengan aman jika terjadi luapan. Pembersih ini dapat mengurangi seluruh kelas korupsi memori dan kerentanan pengungkapan informasi di mana akar penyebabnya adalah integer overflow, seperti kerentanan Stagefright asli.

Contoh dan sumber

Integer Overflow Sanitization (IntSan) disediakan oleh compiler dan menambahkan instrumentasi ke dalam biner selama waktu kompilasi untuk mendeteksi overflow aritmatika. Ini diaktifkan secara default di berbagai komponen di seluruh platform, misalnya /platform/external/libnl/Android.bp .

Penerapan

IntSan menggunakan pembersih luapan bilangan bulat yang ditandatangani dan tidak ditandatangani UBSan. Mitigasi ini diaktifkan pada tingkat per-modul. Ini membantu menjaga komponen penting Android tetap aman dan tidak boleh dinonaktifkan.

Kami sangat menyarankan Anda untuk mengaktifkan Integer Overflow Sanitization untuk komponen tambahan. Kandidat yang ideal adalah kode asli yang diistimewakan atau kode asli yang mem-parsing input pengguna yang tidak tepercaya. Ada overhead kinerja kecil yang terkait dengan pembersih yang bergantung pada penggunaan kode dan prevalensi operasi aritmatika. Harapkan persentase overhead yang kecil dan uji apakah kinerja menjadi perhatian.

Mendukung IntSan di makefiles

Untuk mengaktifkan IntSan di makefile, tambahkan:

LOCAL_SANITIZE := integer_overflow
# Optional features
LOCAL_SANITIZE_DIAG := integer_overflow
LOCAL_SANITIZE_BLACKLIST := modulename_blacklist.txt
  • LOCAL_SANITIZE mengambil daftar pembersih yang dipisahkan koma, dengan integer_overflow menjadi kumpulan opsi yang sudah dikemas sebelumnya untuk masing-masing pembersih integer overflow yang ditandatangani dan tidak ditandatangani dengan daftar hitam default .
  • LOCAL_SANITIZE_DIAG mengaktifkan mode diagnostik untuk pembersih. Gunakan mode diagnostik hanya selama pengujian karena ini tidak akan dibatalkan pada overflow, sepenuhnya meniadakan keuntungan keamanan dari mitigasi. Lihat Pemecahan Masalah untuk detail tambahan.
  • LOCAL_SANITIZE_BLACKLIST memungkinkan Anda menentukan file daftar hitam untuk mencegah fungsi dan file sumber disanitasi. Lihat Pemecahan Masalah untuk detail tambahan.

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 cetak biru

Untuk mengaktifkan sanitasi luapan integer dalam file cetak biru, seperti /platform/external/libnl/Android.bp , tambahkan:

   sanitize: {
      integer_overflow: true,
      diag: {
          integer_overflow: true,
      },
      blacklist: "modulename_blacklist.txt",
   },

Seperti halnya file make, properti integer_overflow adalah kumpulan opsi yang sudah dikemas sebelumnya untuk masing-masing pembersih overflow integer yang ditandatangani dan tidak ditandatangani dengan daftar hitam default .

diag set properti mengaktifkan mode diagnostik untuk pembersih. Gunakan mode diagnostik hanya selama pengujian. Mode diagnostik tidak dibatalkan pada overflow, yang sepenuhnya meniadakan keuntungan keamanan dari mitigasi dalam build pengguna. Lihat Pemecahan Masalah untuk detail tambahan.

Properti blacklist memungkinkan spesifikasi file daftar hitam yang memungkinkan pengembang untuk mencegah fungsi dan file sumber dibersihkan. Lihat Pemecahan Masalah untuk detail tambahan.

Untuk mengaktifkan pembersih satu per satu, gunakan:

   sanitize: {
      misc_undefined: ["signed-integer-overflow", "unsigned-integer-overflow"],
      diag: {
          misc_undefined: ["signed-integer-overflow",
                           "unsigned-integer-overflow",],
      },
      blacklist: "modulename_blacklist.txt",
   },

Penyelesaian masalah

Jika Anda mengaktifkan sanitasi luapan bilangan bulat di komponen baru, atau mengandalkan pustaka platform yang memiliki sanitasi luapan bilangan bulat, Anda mungkin mengalami beberapa masalah dengan luapan bilangan bulat jinak yang menyebabkan pembatalan. Anda harus menguji komponen dengan sanitasi yang diaktifkan untuk memastikan overflow jinak dapat muncul ke permukaan.

Untuk menemukan, pembatalan yang disebabkan oleh sanitasi di build pengguna, cari kerusakan SIGABRT dengan pesan Abort yang menunjukkan overflow yang ditangkap oleh UBSan, seperti:

pid: ###, tid: ###, name: Binder:###  >>> /system/bin/surfaceflinger <<<
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
Abort message: 'ubsan: sub-overflow'

Jejak tumpukan harus menyertakan fungsi yang menyebabkan pembatalan, namun, luapan yang terjadi dalam fungsi sebaris mungkin tidak terlihat dalam pelacakan tumpukan.

Untuk lebih mudah menentukan penyebab utama, aktifkan diagnostik di perpustakaan yang memicu pembatalan dan coba untuk mereproduksi kesalahan. Dengan diagnostik diaktifkan, proses tidak akan dibatalkan dan malah akan terus berjalan. Tidak membatalkan membantu memaksimalkan jumlah overflow jinak di jalur eksekusi tertentu tanpa harus mengkompilasi ulang setelah memperbaiki setiap bug. Diagnostik menghasilkan pesan kesalahan yang menyertakan nomor baris dan file 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 overflow tersebut tidak berbahaya dan dimaksudkan (misalnya tidak memiliki implikasi keamanan). Anda dapat mengatasi pembatalan pembersih dengan:

  • Refactoring kode untuk menghindari overflow ( contoh )
  • Meluap secara eksplisit melalui fungsi __builtin_*_overflow Clang ( contoh )
  • Menonaktifkan sanitasi dalam fungsi dengan menentukan atribut no_sanitize ( contoh )
  • Menonaktifkan sanitasi fungsi atau file sumber melalui file daftar hitam ( contoh )

Anda harus menggunakan solusi yang paling terperinci. Misalnya, fungsi besar dengan banyak operasi aritmatika dan operasi overflow tunggal harus memiliki operasi tunggal yang difaktorkan ulang daripada seluruh fungsi masuk daftar hitam.

Pola umum yang dapat menyebabkan overflow jinak meliputi:

  • Pemeran implisit di mana luapan yang tidak ditandatangani terjadi sebelum dilemparkan ke tipe yang ditandatangani ( contoh )
  • Penghapusan daftar tertaut yang mengurangi indeks loop pada penghapusan ( contoh )
  • Menetapkan jenis yang tidak ditandatangani ke -1 alih-alih menentukan nilai maks aktual ( contoh )
  • Loop yang mengurangi unsigned integer dalam kondisi ( contoh , contoh )

Direkomendasikan bahwa pengembang memastikan bahwa kasus di mana pembersih mendeteksi luapan yang memang jinak tanpa efek samping yang tidak diinginkan atau implikasi keamanan sebelum menonaktifkan sanitasi.

Menonaktifkan IntSan

Anda dapat menonaktifkan IntSan dengan daftar hitam atau atribut fungsi. Nonaktifkan dengan hemat dan hanya jika pemfaktoran ulang kode tidak masuk akal atau jika ada overhead kinerja yang bermasalah.

Lihat dokumentasi Clang upstream untuk informasi lebih lanjut tentang menonaktifkan IntSan dengan atribut fungsi dan pemformatan file daftar hitam . Daftar hitam harus dicakup untuk pembersih tertentu dengan menggunakan nama bagian yang menentukan pembersih target untuk menghindari dampak pembersih lainnya.

Validasi

Saat ini, tidak ada tes CTS khusus untuk Sanitasi Integer Overflow. Sebagai gantinya, pastikan tes CTS lulus dengan atau tanpa mengaktifkan IntSan untuk memverifikasi bahwa itu tidak memengaruhi perangkat.