Bagikan melalui


Byte bayangan AddressSanitizer

Kami secara singkat meringkas konsep byte bayangan dan bagaimana mereka dapat digunakan oleh implementasi runtime ./fsanitize=address Untuk detail lebih lanjut, kami merujuk Anda ke penelitian awal AddressSanitizer - Serebryany, dkk dan dokumentasi algoritma AddressSanitizer saat ini.

Konsep inti

Setiap 8 byte di ruang alamat virtual aplikasi Anda dapat dijelaskan menggunakan satu byte bayangan.

Satu byte bayangan menjelaskan berapa banyak byte yang saat ini dapat diakses sebagai berikut:

  • 0 berarti semua 8 byte
  • 1-7 berarti satu hingga tujuh byte
  • Konteks pengodean angka negatif untuk runtime yang digunakan untuk melaporkan diagnostik.

Legenda byte bayangan

Pertimbangkan legenda byte bayangan ini di mana semua angka negatif didefinisikan:

Cuplikan layar legenda byte bayangan AddressSanitizer.

Pemetaan - menjelaskan ruang alamat Anda

Setiap 8 byte di ruang alamat virtual aplikasi yang selaras "0-mod-8" dapat dipetakan ke byte bayangan yang menjelaskan slot tersebut di ruang alamat virtual. Pemetaan ini dapat dicapai dengan shift sederhana dan menambahkan.

Pada x86:

char shadow_byte_value = *((Your_Address >> 3) + 0x30000000)

Pada x64:

char shadow_byte_value = *((Your_Address >> 3) + _asan_runtime_assigned_offset)

Pembuatan kode - pengujian

Pertimbangkan bagaimana byte bayangan tertentu mungkin ditulis, baik oleh kode yang dihasilkan kompilator, data statis, atau runtime. Kode semu ini menunjukkan bagaimana mungkin untuk menghasilkan pemeriksaan yang mendahului beban atau penyimpanan apa pun:

ShadowAddr = (Addr >> 3) + Offset;
if (*ShadowAddr != 0) {
    ReportAndCrash(Addr);
}

Saat melengkapi referensi memori yang lebarnya kurang dari 8 byte, instrumentasinya sedikit lebih kompleks. Jika nilai bayangan positif (yang berarti hanya byte k pertama dalam kata 8-byte yang dapat diakses), kita perlu membandingkan 3 bit terakhir alamat dengan k.

ShadowAddr = (Addr >> 3) + Offset;
k = *ShadowAddr;
if (k != 0 && ((Addr & 7) + AccessSize > k)) {
    ReportAndCrash(Addr);
}

Runtime dan kode yang dihasilkan kompilator, baik byte bayangan tulis. Byte bayangan ini mengizinkan atau mencabut akses saat cakupan berakhir atau penyimpanan dibeberkan. Pemeriksaan di atas membaca byte bayangan yang menjelaskan "slot" 8 byte di ruang alamat aplikasi Anda, pada waktu tertentu dalam eksekusi program. Selain pemeriksaan yang dihasilkan secara eksplisit ini, runtime juga memeriksa byte bayangan setelah menyadap (atau "kait") banyak fungsi dalam CRT.

Untuk informasi selengkapnya, lihat daftar fungsi yang disadap.

Mengatur byte bayangan

Baik kode yang dihasilkan kompilator dan runtime AddressSanitizer dapat menulis byte bayangan. Misalnya, pengkompilasi dapat mengatur byte bayangan untuk memungkinkan akses berukuran tetap ke lokal tumpukan yang ditentukan dalam cakupan dalam. Runtime dapat mengelilingi variabel global di bagian data dengan byte bayangan.

Lihat juga

Gambaran umum AddressSanitizer
Masalah yang diketahui AddressSanitizer
Referensi bahasa dan build AddressSanitizer
Referensi runtime AddressSanitizer
AddressSanitizer cloud atau pengujian terdistribusi
Integrasi debugger AddressSanitizer
Contoh kesalahan AddressSanitizer