Apakah mungkin untuk membaca memori dari program lain dengan mengalokasikan semua ruang kosong pada suatu sistem?

26

Secara teoritis, jika saya membangun sebuah program yang mengalokasikan semua memori yang tidak digunakan pada suatu sistem, dan terus meminta semakin banyak memori ketika aplikasi lain mengeluarkan memori yang tidak lagi mereka perlukan, mungkinkah membaca memori yang baru dirilis dari aplikasi lain ? Atau apakah ini entah bagaimana dilindungi oleh sistem operasi modern?

Saya tidak punya aplikasi praktis untuk ini, saya hanya ingin tahu. Saya menyadari ada beberapa masalah dengan mengalokasikan "semua memori yang tersedia" di kehidupan nyata.

Sunting: Untuk memperjelas, saya bertanya secara spesifik tentang memori "Dirilis", tidak mengakses memori yang saat ini dialokasikan oleh aplikasi lain.

ConditionRacer
sumber

Jawaban:

23

Tidak, karena kernel yang baik menghapus isi memori sebelum dikeluarkan untuk melindungi dari serangan yang Anda usulkan.

Pada sistem Unixy, memori dialokasikan untuk proses dengan memperluas apa yang disebut program break , yang merupakan batas ruang yang bisa ditangani secara virtual. Sebuah proses memberi tahu kernel bahwa ia ingin memperluas ruang yang bisa dialamatkan, dan kernel akan mengizinkannya jika memori tersedia atau panggilan akan gagal jika tidak. (Nama brk()panggilan sistem berasal dari konsep ini.)

Dalam praktiknya, sejumlah besar memori yang dibebaskan tidak sering bertabrakan dengan jeda program, yang akan diperlukan untuk proses mengembalikan memori ke kernel dengan menyusutkan jeda program. Ini, tentu saja, semua tergantung pada implementasi sistem Anda dari malloc()dan free(). Jika Anda memiliki sumber yang tersedia, mereka akan memberi tahu Anda apakah memori pernah dikembalikan atau tidak.

Tidak ada implikasi keamanan untuk malloc()tidak menginisialisasi memori karena apa pun yang didapatnya brk()akan dihapus dan apa pun yang sebelumnya free()akan ditulis oleh proses yang sama.

Blrfl
sumber
19

Ya, secara teori dimungkinkan untuk membaca memori yang dikeluarkan proses lain. Itu adalah sumber dari sejumlah serangan eskalasi hak istimewa kembali pada hari itu. Karena itu, sistem operasi saat ini secara efektif nol kehabisan memori jika sebelumnya dialokasikan oleh proses lain. Alasan Anda tidak selalu melihat memori zeroed out adalah karena lebih efisien untuk tidak zero out memory jika sebelumnya dialokasikan oleh proses yang sama. OS mencoba mengembalikan halaman memori ke proses yang sama jika bisa.

Karl Bielefeldt
sumber
1
"Ya tapi tidak" adalah "tidak". @ Blrfl sudah benar.
Ross Patterson
4
@RossPatterson: Pada titik teoretis, Karl sebenarnya lebih benar daripada saya. Kenyataan praktisnya adalah bahwa sistem operasi utama menutup lubang itu bertahun-tahun yang lalu.
Blrfl
@ Blrfl Dipahami. Tetapi "tahun lalu" adalah di akhir 1960-an, ketika sistem paging dan memori virtual pertama kali diperkenalkan. Tentunya pada saat Multics, VM / 370, dan OS / VS. Tidak ada bug, ini tidak mungkin dalam memori sebagian besar programmer yang berlatih.
Ross Patterson
The reason you don't always see zeroed out memory is because it is more efficient not to zero out the memory if it was previously allocated by the same process Saya melihat beberapa inkonsistensi di sini. Apakah maksud Anda "eksekusi yang sama"? Bagaimana cara memeriksa apakah tidak nol - oleh jalur disk?
jakub.g
1
Saya pikir saya kehilangan sesuatu. Lalu mengapa, ketika saya mengkompilasi dan menjalankan beberapa program C ++ dengan, katakanlah, bilangan bulat tidak diinisialisasi, mereka tidak sama dengan 0 ketika saya membaca variabel-variabel itu?
jakub.g
2

Ada beberapa lapisan yang terlibat di sini yang mempengaruhi jawabannya.

Jika Anda menggunakan sistem operasi memori virtual modern, Anda tidak akan dapat melihat sisa-sisa data proses lain di halaman yang Anda alokasikan.

Saat proses pertama kali dimuat, tabel halaman dimuat, dan berpotensi frame memori nyata dialokasikan ke halaman-halaman tersebut. Minimal, tabel halaman atau tabel tambahannya, akan berisi peta semua memori yang dapat dialokasikan proses. Ini juga di mana proses awal istirahat, yang disebutkan di atas, akan ditetapkan.

Sementara malloc () dapat, jika proses diizinkan, menyebabkan proses istirahat berubah, menambahkan lebih banyak halaman ke tabel proses (halaman tambahan) untuk memenuhi permintaan, tempat di mana satu proses dapat "mendapatkan yang lain" memproses data di lapisan memori nyata yang lebih rendah.

Dalam kedua skenario ini, sistem operasi modern yang menggunakan paging permintaan, atau alokasi malas, belum mengalokasikan memori fisik (frame). Sistem operasi hanya "membuat catatan" tentang memori virtual mana yang dianggap sah. Memori aktual hanya akan diberikan bila diperlukan.

Memori fisik atau frame dialokasikan ke proses ketika halaman virtual direalisasikan dan dipetakan ke dalam tabel halaman proses Di sinilah potensi eksposur data ada. Ini terjadi selama kesalahan halaman. Eksposur adalah karena proses sebelumnya mungkin telah menggunakan frame yang sama dan datanya baik ditinggalkan atau ditukar, untuk memberikan ruang bagi permintaan memori fisik saat ini. Sistem operasi harus berhati-hati untuk memastikan bahwa data proses yang diminta ditukar dengan benar atau bingkai dibersihkan (memusatkan perhatian) sebelum melanjutkan proses. Ini juga disebutkan di atas sebagai masalah "lama tapi terpecahkan".

Ini membuatnya agak tidak relevan jika memori proses lain "dirilis" atau tidak. Memori lain yang "dilepaskan" proses masih berada di halaman yang ditugaskan untuk proses itu dan biasanya tidak dipetakan sampai proses berakhir karena mereka hanya akan ditukar ketika memori menjadi rendah atau mereka diusir. malloc () dan free () mengelola memori virtual yang ditugaskan untuk proses di tingkat (pengguna).

Dalam pertanyaan Anda, proses Anda, terus-menerus meminta semakin banyak memori, secara teori, mendorong semua proses lain keluar dari memori. Pada kenyataannya, ada strategi alokasi bingkai - global dan lokal - yang dapat mempengaruhi jawaban juga. Sangat mungkin bahwa proses akan memaksa halaman sendiri kehabisan memori sebelum diizinkan untuk membanjiri sistem operasi dan semua proses lainnya. Meskipun ini melampaui pertanyaan awal Anda.

Semua ini diperdebatkan dalam sistem seperti MS-DOS. MS-DOS (dan lainnya, sistem yang lebih sederhana) tidak menggunakan memori virtual (sendiri) dan Anda dapat dengan mudah menyodok dan mendorong data "proses" lainnya.

Beberapa referensi yang bagus, yang mungkin lebih mudah dipahami daripada kode sumber Linux adalah buku teks sistem operasi yang baik, Konsep Sistem Operasi oleh Silberscatz, Gavin, dan Gange, atau Desain Sistem Operasi oleh Andrew Tanenbaum. Juga sesuatu seperti Nachos dari Berkeley atau Pintos dari Stanford adalah sistem operasi kecil yang dibangun untuk belajar dan memiliki ide-ide yang sama di dalamnya.

0xACE
sumber
0

Saya mencoba ini di Ubuntu 16,04 bulan yang lalu. Seperti yang dikatakan 0xACE, OS modern mengalokasikan semua-nol, halaman virtual setelah Anda memanggil malloc (). Tetapi, jika Anda tidak menulis apa pun ke buffer yang dialokasikan, itu tidak akan dipetakan ke memori fisik (yaitu, prinsip copy-on-write), sehingga Anda akan selalu membaca nol dari blok "tidak diinisialisasi". Mungkin ada beberapa embedded OS yang dikompilasi dengan opsi "CONFIG_MMAP_ALLOW_UNITIALIZED" untuk kinerja yang lebih baik, dalam hal ini Anda bisa mendapatkan apa yang Anda harapkan.

weir007
sumber
-1

Tidak, ini tidak memungkinkan program lain membaca memori orang lain berkat keajaiban paging . Dengan cara ini, total penggunaan memori dapat melebihi ram fisik dengan melepas bagian-bagiannya ke harddisk.

Juga, memori maksimum suatu proses dapat mengalokasikan dibatasi oleh OS (hingga 4 gigs untuk arsitektur 32 bit) setelah itu allocpanggilan berikutnya akan mengembalikan kesalahan kehabisan memori.

ratchet freak
sumber
Apakah tidak ada API khusus platform yang dapat mengelak dari ini? Jujur saya tidak tahu, tapi saya tidak akan terkejut (misalnya, Linux memungkinkan mencegah OS dari memindahkan halaman dari memori fisik, via mlock).
Jika ada 4 GB RAM dan paging dibatasi hingga 8 GB, bagaimana jika aplikasi meminta 12 GB (pada x64)?
Arseni Mourzenko
maka panggilan sistem akan mengembalikan kesalahan ketika memori yang tersisa terlalu sedikit, atau komputer akan berhenti ketika tidak ada yang tersisa ...
ratchet freak
4
Dia tidak bertanya tentang membaca ingatan orang lain, melainkan membaca ingatan yang TERLEBIH DAHULU. Bagian ram saat ini gratis, dan .... Saya tidak berpikir ... bahwa skema paging nol memori setelah itu dibebaskan. Jadi program akan mengalokasikan blok memori, dan menganalisis data yang tidak diinisialisasi yang sudah ada.
Philip
@ philip benar, saya bertanya secara spesifik tentang memori yang dirilis.
ConditionRacer