Apakah stack overflow terdeteksi oleh perangkat keras atau perangkat lunak?

26

Apakah tugas perangkat lunak (sistem operasi) untuk mendeteksi stack overflow atau apakah stack overflow terdeteksi di perangkat keras, menyebabkan pengecualian pada CPU?

gilianzz
sumber
Saya akan mengatakan perangkat keras, melalui kesalahan MMU pada sebagian besar CPU. x86 dalam mode 32bits memiliki segmentasi selain paging, dan "Stack Segment" dikaitkan, seperti segmen Code, Data, Ext ... dengan alamat basis dan ukuran. Akses apa pun di luar rentang itu akan memicu kesalahan.
TEMLIB

Jawaban:

25

Ini bisa berupa perangkat lunak, atau perangkat keras, atau keduanya, atau tidak sama sekali.

Ada dua jenis overflow: overflow saat menumbuhkan stack (saat memasukkan fungsi), dan overflow saat mengakses array pada stack. Meluap ketika menumbuhkan tumpukan dapat dideteksi dengan membuat batas memeriksa entri fungsi, untuk memverifikasi bahwa ada cukup ruang (dan memberi sinyal kesalahan atau menumbuhkan tumpukan jika tidak ada). Meluap saat mengakses array di stack hanya merupakan masalah dalam bahasa tingkat rendah yang tidak memverifikasi batas array; solusinya adalah memverifikasi batas array.

Pendekatan perangkat lunak ini memiliki keunggulan bahwa mereka bekerja sepenuhnya andal: Anda dapat yakin bahwa setiap stack overflow akan terdeteksi. Kelemahan mereka adalah mereka meningkatkan ukuran kode dan waktu eksekusi. Perangkat keras dapat membantu dengan menyediakan metode untuk mendeteksi sebagian besar luapan tanpa biaya selama tidak terjadi luapan. Pada arsitektur dengan MMU ¹, lingkungan runtime dapat mengatur untuk memetakan tumpukan pada batas halaman, dengan halaman berikutnya tetap tidak dipetakan.

+---------------+---------------+---------------+---------------+
| stack                         | unmapped      | other stuff   |
|    ----> direction of growth  |               |               |
+---------------+---------------+---------------+---------------+
^               ^               ^               ^               ^  page boundaries

Dengan begitu, jika perangkat lunak mencoba mengakses data di luar batas halaman (apakah karena penunjuk tumpukan telah bergerak di luar batas atau karena akses array di luar batas dan di luar batas), itu akan menyebabkan kesalahan dengan mengakses area yang tidak dipetakan . Ini hanya terjadi jika overflow cukup kecil: jika jumlah overflow terlalu besar, program mungkin pada akhirnya mengakses hal-hal lain di sisi lain dari celah di ruang alamat.

Kelemahan dari pendekatan perangkat keras adalah bahwa itu tidak sepenuhnya dapat diandalkan karena meluap dengan jumlah besar mungkin tidak terdeteksi, dan bahwa itu tidak mendeteksi limpahan array yang tetap dalam ruang addressable.

Untuk mendeteksi kelebihan array, teknik perangkat lunak lain adalah kenari : letakkan nilai khusus di bagian atas tumpukan atau di antara frame, dan periksa bahwa nilai kenari tidak berubah pada pengembalian fungsi. Ini juga merupakan teknik yang tidak sempurna karena overflow mungkin menghindari kenari sama sekali atau mungkin tidak terdeteksi karena nilai kenari telah dipulihkan pada saat diperiksa. Meskipun demikian, akan berguna untuk membuatnya lebih sulit untuk mengeksploitasi beberapa kerentanan keamanan.

Cara teraman dan termurah untuk menghindari tumpukan berlebih adalah dengan menghitung jumlah tumpukan yang diperlukan program sebelum mulai menjalankannya, dengan analisis statis. Namun ini tidak selalu praktis: jumlah tumpukan yang dibutuhkan oleh suatu program secara umum tidak dapat ditentukan dan tergantung pada data yang dimanipulasi oleh program tersebut.

¹ Prinsip yang sama juga dapat diterapkan hanya dengan MPU, atau tanpa perlindungan memori jika ada utas tunggal yang tumpukannya berada di tepi pemetaan fisik yang ada.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
4
Saya tidak akan memanggil array out-of-bounds mengakses stack overflow, bahkan jika array ada di stack. Itu hanya kasus khusus buffer overflow.
CodesInChaos
Tidak mengalokasikan ke item tumpukan utama yang direferensikan relatif ke non-stack / frame pointer atau offset non-konstan akan menghindari kelebihan tumpukan tradisional. Menggunakan tumpukan alamat pengirim yang terpisah (atau tumpukan tumpahan RA / register seperti Itanium) setidaknya akan sangat mengurangi peluang pemrograman berorientasi-kembali.
Paul A. Clayton
Akses di luar batas lebih tepat disebut overrun , bukan overflow.
Ben Voigt
3
@ awesomebing1 tidak setiap platform mendeteksi stack overflows. Anda mungkin hanya akan menimpa apa pun yang terjadi setelah tumpukan (mirip dengan buffer overflow lainnya).
user253751
1
@CodesInChaos, terkadang buffer overflow dalam buffer yang dialokasikan stack disebut "stack overflows" (singkatnya). Memang, terminologi itu bisa sedikit membingungkan tanpa konteks.
DW