Bagaimana kernel mencegah program jahat membaca semua RAM fisik?

10

Jika saya menulis sebuah program yang mencoba membaca memori di setiap alamat yang mungkin, dan saya menjalankannya pada Unix "penuh", ia tidak akan dapat mengakses semua RAM fisik. Tetapi bagaimana sistem operasi mencegahnya?

Saya lebih akrab dengan arsitektur CPU kecil di mana setiap bagian dari kode perakitan dapat mengakses semuanya. Saya tidak mengerti bagaimana suatu program (kernel) dapat mendeteksi operasi berbahaya seperti itu.

sekarang
sumber
2
Biasanya MMU berhati-hati agar Anda tidak dapat mengakses memori di luar area yang diizinkan.
ott--
1
Nah, MMU dikonfigurasikan oleh majelis. Dengan demikian kode perakitan dapat mengubah konfigurasi MMU dan mengakses halaman memori yang berbeda, bukan?
nowox
Ini hanya benar jika Anda menjalankan kode Anda sebagai root.
ott--
2
Anda harus membaca tentang tabel-halaman dan abstraksi kernel di sana.
Clarus
@ott: bahkan root tidak dapat memodifikasi MMU (setidaknya tidak di Linux). Hanya kernel yang melakukannya.
Basile Starynkevitch

Jawaban:

12

Bukan kernel yang mencegah akses memori buruk, melainkan CPU. Peran kernel hanya untuk mengkonfigurasi CPU dengan benar.

Lebih tepatnya, komponen perangkat keras yang mencegah akses memori buruk adalah MMU . Ketika sebuah program mengakses alamat memori, alamat tersebut diterjemahkan oleh CPU berdasarkan konten MMU. MMU membuat terjemahan dari alamat virtual ke alamat fisik: ketika CPU melakukan pemuatan atau penyimpanan pada alamat virtual tertentu, itu menghitung alamat fisik yang sesuai berdasarkan konten MMU. Kernel mengatur konfigurasi MMU sedemikian rupa sehingga setiap program hanya dapat mengakses memori yang menjadi haknya. Register memori dan perangkat keras program lain sama sekali tidak dipetakan dalam memori program: alamat fisik ini tidak memiliki alamat virtual yang sesuai dalam konfigurasi MMU untuk program itu.

Pada pergantian konteks antara proses yang berbeda, kernel memodifikasi konfigurasi MMU sehingga berisi terjemahan yang diinginkan untuk proses baru.

Beberapa alamat virtual tidak dipetakan sama sekali, yaitu MMU menerjemahkannya ke nilai “no address address” khusus. Ketika prosesor mereferensikan alamat yang tidak dipetakan, ini menyebabkan jebakan: prosesor bercabang ke lokasi yang telah ditentukan dalam kode kernel. Beberapa jebakan adalah sah; misalnya alamat virtual dapat sesuai dengan halaman yang ada dalam ruang swap , dalam hal ini kode kernel akan memuat konten halaman dari swap kemudian beralih kembali ke program asli sedemikian rupa sehingga instruksi akses memori dieksekusi lagi. Perangkap lain tidak sah, dalam hal ini proses menerima sinyal yang secara default membunuh program dengan segera (dan jika tidak bercabang ke pengendali sinyal dalam program: dalam hal apa pun instruksi akses memori tidak selesai).

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Bisakah Anda menentukan sedikit pernyataan "alamat didekodekan oleh CPU berdasarkan konten MMU" ? Apakah ada kode aktual dalam program yang sedang berjalan yang menerjemahkan alamat? Atau ketika CPU membuat akses ke alamat - akses dilakukan ke MMU, yang menerjemahkan / menanganinya dengan benar (membuat akses ke memori atau cache dan mengembalikan hasilnya, atau memicu prosedur kernel)? Jadi, dari perspektif mikrokontroler / perakitan, MMU adalah bagian baru. CPU tidak terhubung langsung ke memori, itu terhubung ke MMU dan di situlah abstraksi kehabisan memori virtual dilakukan.
xealits
3
@xealits Terjemahan dari alamat virtual ke alamat fisik dilakukan di dalam MMU, yang merupakan rangkaian perangkat keras. Tidak ada kode untuk melakukan itu di program atau di kernel. Kernel hanya dipanggil dalam kasus luar biasa, ketika program mencoba mengakses alamat virtual yang mana entri MMU mengatakan "alamat tidak valid". Kernel juga melakukan pekerjaan mengkonfigurasi register dan tabel dalam RAM yang digunakan MMU.
Gilles 'SO- stop being evil'