GNU/Linux >> Belajar Linux >  >> Linux

Larang akses memori yang tidak selaras pada x86/x86_64

Baik GCC dan Dentang memiliki UndefinedBehaviorSanitizer bawaan. Salah satu pemeriksaan itu, alignment , dapat diaktifkan dengan -fsanitize=alignment . Ini akan mengeluarkan kode untuk memeriksa perataan penunjuk saat waktu proses dan membatalkan jika penunjuk yang tidak selaras didereferensi.

Lihat dokumentasi online di:

  • https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html

Ini rumit dan saya belum melakukannya secara pribadi, tetapi menurut saya Anda dapat melakukannya dengan cara berikut:

x86_64 CPU (khususnya saya telah memeriksa Intel Corei7 tetapi saya kira yang lain juga) memiliki penghitung kinerja MISALIGN_MEM_REF yang melawan referensi memori yang tidak selaras.

Jadi pertama-tama, Anda dapat menjalankan program dan menggunakan alat "perf" di Linux untuk menghitung jumlah akses tidak selaras yang telah dilakukan kode Anda.

Peretasan yang lebih rumit dan menarik adalah dengan menulis modul kernel yang memprogram penghitung kinerja untuk menghasilkan interupsi pada luapan dan membuatnya meluap pada beban/penyimpanan pertama yang tidak selaras. Tanggapi interupsi ini dalam modul kernel Anda tetapi mengirimkan sinyal ke proses Anda.

Akibatnya, ini akan mengubah x86_64 menjadi inti yang tidak mendukung akses yang tidak selaras.

Ini tidak akan mudah - selain kode Anda, pustaka sistem juga menggunakan akses yang tidak selaras, jadi akan sulit untuk memisahkannya dari kode Anda sendiri.


Saya baru saja membaca pertanyaan Apakah akses memori yang tidak selaras selalu menyebabkan kesalahan bus? yang ditautkan ke Kesalahan Segmentasi artikel Wikipedia.

Dalam artikel tersebut, ada pengingat yang bagus tentang bendera prosesor Intel yang agak tidak biasa AC alias Alignment Check.

Dan inilah cara mengaktifkannya (dari contoh Kesalahan Bus Wikipedia, dengan bug clobber zona merah diperbaiki untuk Sistem V x86-64 jadi ini aman di Linux dan MacOS, dan dikonversi dari Basic asm yang tidak pernah merupakan ide bagus di dalam fungsi:Anda ingin perubahan pada AC dipesan dengan akses memori.

#if defined(__GNUC__)
# if defined(__i386__)
    /* Enable Alignment Checking on x86 */
    __asm__("pushf\n orl $0x40000,(%%esp)\n popf" ::: "memory");
# elif defined(__x86_64__) 
     /* Enable Alignment Checking on x86_64 */
    __asm__("add $-128, %%rsp \n"    // skip past the red-zone, in case there is one and the compiler has local vars there.
            "pushf\n"
            "orl $0x40000,(%%rsp)\n"
            "popf \n"
            "sub $-128, %%rsp"       // and restore the stack pointer.
           ::: "memory");       // ordered wrt. other mem access
# endif
#endif

Setelah diaktifkan, ini berfungsi seperti pengaturan penyelarasan ARM di /proc/cpu/alignment , lihat jawaban Bagaimana menjebak akses memori yang tidak selaras? untuk contoh.

Selain itu, jika Anda menggunakan GCC, saya sarankan Anda mengaktifkan -Wcast-align peringatan. Saat membangun untuk target dengan persyaratan penyelarasan yang ketat (misalnya ARM), GCC akan melaporkan lokasi yang mungkin menyebabkan akses memori yang tidak selaras.

Tetapi perhatikan bahwa asm tulisan tangan libc untuk memcpy dan fungsi lainnya masih akan membuat akses tidak selaras, jadi pengaturan AC seringkali tidak praktis pada x86 (termasuk x86-64). GCC terkadang akan memancarkan asm yang membuat akses tidak selaras meskipun sumber Anda tidak melakukannya, mis. sebagai pengoptimalan untuk menyalin atau membidik dua elemen larik yang berdekatan atau anggota struktur sekaligus.


Linux
  1. Linux – Penggunaan Memori Nyata?

  2. Mengukur Penggunaan Ram Suatu Program?

  3. Diagnostik memori rendah Windows

  1. Batas memori PHP

  2. Apakah realloc menjaga penyelarasan memori posix_memalign?

  3. Bagaimana mengalokasikan memori yang ukuran halamannya selaras?

  1. Penggunaan Memori Linux

  2. Cara Menghapus Cache Memori di Linux

  3. Grep:Memori Habis?