Di komputer, agar suatu proses dapat dieksekusi, itu perlu ditempatkan di memori. Untuk ini, bidang harus ditetapkan ke proses dalam memori. Alokasi memori adalah masalah penting yang harus diperhatikan, terutama dalam arsitektur kernel dan sistem.

Mari kita lihat alokasi memori Linux secara rinci dan memahami apa yang terjadi di balik layar.

Bagaimana Alokasi Memori Dilakukan?

Kebanyakan software engineer tidak mengetahui detail dari proses ini. Tetapi jika Anda adalah kandidat programmer sistem, Anda harus tahu lebih banyak tentangnya. Saat melihat proses alokasi, perlu sedikit detail tentang Linux dan glibc Perpustakaan.

Ketika aplikasi membutuhkan memori, mereka harus memintanya dari sistem operasi. Permintaan dari kernel ini secara alami akan membutuhkan panggilan sistem. Anda tidak dapat mengalokasikan memori sendiri dalam mode pengguna.

Itu mallok() keluarga fungsi bertanggung jawab untuk alokasi memori dalam bahasa C. Pertanyaan untuk ditanyakan di sini adalah apakah malloc(), sebagai fungsi glibc, membuat panggilan sistem langsung.

instagram viewer

Tidak ada panggilan sistem yang disebut malloc di kernel Linux. Namun, ada dua panggilan sistem untuk permintaan memori aplikasi, yaitu: brk dan mmap.

Karena Anda akan meminta memori dalam aplikasi Anda melalui fungsi glibc, Anda mungkin bertanya-tanya panggilan sistem mana yang digunakan glibc saat ini. Jawabannya adalah keduanya.

Panggilan Sistem Pertama: brk

Setiap proses memiliki bidang data yang berdekatan. Dengan panggilan sistem brk, nilai jeda program, yang menentukan batas bidang data, meningkat dan proses alokasi dilakukan.

Meskipun alokasi memori dengan metode ini sangat cepat, tidak selalu mungkin untuk mengembalikan ruang yang tidak terpakai ke sistem.

Misalnya, pertimbangkan bahwa Anda mengalokasikan lima bidang, masing-masing berukuran 16KB, dengan panggilan sistem brk melalui fungsi malloc(). Ketika Anda selesai dengan nomor dua dari bidang ini, tidak mungkin untuk mengembalikan sumber daya yang relevan (dealokasi) sehingga sistem dapat menggunakannya. Karena jika Anda mengurangi nilai alamat untuk menunjukkan tempat dimulainya bidang nomor dua Anda, dengan panggilan ke brk, Anda telah melakukan dealokasi untuk bidang nomor tiga, empat, dan lima.

Untuk mencegah kehilangan memori dalam skenario ini, implementasi malloc di glibc memantau tempat yang dialokasikan di bidang data proses dan kemudian menentukan untuk mengembalikannya ke sistem dengan fungsi free(), sehingga sistem dapat menggunakan ruang kosong untuk memori lebih lanjut alokasi.

Dengan kata lain, setelah lima area 16KB dialokasikan, jika area kedua dikembalikan dengan fungsi free() dan area 16KB lainnya diminta lagi setelah beberapa saat, alih-alih memperbesar area data melalui panggilan sistem brk, alamat sebelumnya dikembalikan.

Namun, jika area yang baru diminta lebih besar dari 16KB, maka area data akan diperbesar dengan mengalokasikan area baru dengan system call brk karena area dua tidak dapat digunakan. Meskipun area nomor dua tidak digunakan, aplikasi tidak dapat menggunakannya karena perbedaan ukuran. Karena skenario seperti ini, ada situasi yang disebut fragmentasi internal, dan pada kenyataannya, Anda jarang dapat menggunakan semua bagian memori secara maksimal.

Untuk pemahaman yang lebih baik, coba kompilasi dan jalankan aplikasi contoh berikut:

#termasuk <stdio.h>
#termasuk <stdlib.h>
#termasuk <unistd.h>
ke dalamutama(ke dalam argc, arang*argv[])
{
arang *ptr[7];
ke dalam n;
cetakf("Pid dari %s: %d", argv[0], getpid());
cetakf("Istirahat program awal: %p", sbrk (0));
untuk (n=0; n<5; n++) ptr[n] = malloc (16 * 1024);
cetakf("Setelah 5 x 16kB malloc: %p", sbrk (0));
Gratis(ptr[1]);
cetakf("Setelah bebas dari 16kB kedua: %p", sbrk (0));
ptr[5] = malloc (16 * 1024);
cetakf("Setelah mengalokasikan 6 dari 16kB: %p", sbrk (0));
Gratis(ptr[5]);
cetakf("Setelah membebaskan blok terakhir: %p", sbrk (0));
ptr[6] = malloc (18 * 1024);
cetakf("Setelah mengalokasikan 18kB baru: %p", sbrk (0));
getchar();
kembali0;
}

Saat Anda menjalankan aplikasi, Anda akan mendapatkan hasil yang mirip dengan output berikut:

Pid dari ./a.out: 31990
Program awal merusak: 0x55ebcadf4000
Setelah 5 x 16kB malloc: 0x55ebcadf4000
Setelah bebas dari 16kB kedua: 0x55ebcadf4000
Setelah mengalokasikan ke-6 dari 16kB: 0x55ebcadf4000
Setelah membebaskan blok terakhir: 0x55ebcadf4000
Setelah mengalokasikan baru18kB: 0x55ebcadf4000

Output untuk brk dengan strace adalah sebagai berikut:

brk(BATAL) = 0x5608595b6000
brk (0x5608595d7000) = 0x5608595d7000

Seperti yang terlihat, 0x21000 telah ditambahkan ke alamat akhir bidang data. Anda dapat memahami ini dari nilainya 0x5608595d7000. Jadi kira-kira 0x21000, atau 132KB memori dialokasikan.

Ada dua poin penting yang perlu diperhatikan di sini. Yang pertama adalah alokasi lebih dari jumlah yang ditentukan dalam kode sampel. Lain adalah baris kode mana yang menyebabkan panggilan brk yang menyediakan alokasi.

Pengacakan Tata Letak Ruang Alamat: ASLR

Saat Anda menjalankan contoh aplikasi di atas satu demi satu, Anda akan melihat nilai alamat yang berbeda setiap kali. Membuat ruang alamat berubah secara acak dengan cara ini secara signifikan mempersulit pekerjaan serangan keamanan dan meningkatkan keamanan perangkat lunak.

Namun, dalam arsitektur 32-bit, delapan bit umumnya digunakan untuk mengacak ruang alamat. Meningkatkan jumlah bit tidak akan sesuai karena area yang dapat dialamatkan di atas bit yang tersisa akan sangat rendah. Juga, penggunaan kombinasi hanya 8-bit tidak membuat hal-hal cukup sulit bagi penyerang.

Dalam arsitektur 64-bit, di sisi lain, karena ada terlalu banyak bit yang dapat dialokasikan untuk operasi ASLR, keacakan yang jauh lebih besar disediakan, dan tingkat keamanan meningkat.

Kernel Linux juga mendukung Perangkat berbasis Android dan fitur ASLR diaktifkan sepenuhnya di Android 4.0.3 dan yang lebih baru. Bahkan untuk alasan ini saja, tidak salah untuk mengatakan bahwa smartphone 64-bit memberikan keuntungan keamanan yang signifikan dibandingkan versi 32-bit.

Dengan menonaktifkan sementara fitur ASLR dengan perintah berikut, akan terlihat bahwa aplikasi pengujian sebelumnya mengembalikan nilai alamat yang sama setiap kali dijalankan:

gema0 | sudo tee /proc/sys/kernel/randomize_va_space

Untuk mengembalikannya ke keadaan sebelumnya, cukup menulis 2 alih-alih 0 dalam file yang sama.

Panggilan Sistem Kedua: mmap

mmap adalah panggilan sistem kedua yang digunakan untuk alokasi memori di Linux. Dengan panggilan mmap, ruang kosong di area memori mana pun dipetakan ke ruang alamat dari proses panggilan.

Dalam alokasi memori yang dilakukan dengan cara ini, ketika Anda ingin mengembalikan partisi 16KB kedua dengan fungsi free() pada contoh brk sebelumnya, tidak ada mekanisme untuk mencegah operasi ini. Segmen memori yang relevan dihapus dari ruang alamat proses. Itu ditandai sebagai tidak lagi digunakan dan dikembalikan ke sistem.

Karena alokasi memori dengan mmap sangat lambat dibandingkan dengan yang menggunakan brk, maka diperlukan alokasi brk.

Dengan mmap, setiap area memori yang kosong dipetakan ke ruang alamat proses, sehingga isi dari ruang yang dialokasikan direset sebelum proses ini selesai. Jika reset tidak dilakukan dengan cara ini, data milik proses yang sebelumnya menggunakan area memori yang relevan juga dapat diakses oleh proses yang tidak terkait berikutnya. Ini akan membuat mustahil untuk berbicara tentang keamanan dalam sistem.

Pentingnya Alokasi Memori di Linux

Alokasi memori sangat penting, terutama dalam masalah optimasi dan keamanan. Seperti yang terlihat pada contoh di atas, tidak sepenuhnya memahami masalah ini dapat berarti menghancurkan keamanan sistem Anda.

Bahkan konsep yang mirip dengan push dan pop yang ada di banyak bahasa pemrograman didasarkan pada operasi alokasi memori. Mampu menggunakan dan menguasai memori sistem dengan baik sangat penting baik dalam pemrograman sistem tertanam maupun dalam mengembangkan arsitektur sistem yang aman dan optimal.

Jika Anda juga ingin mendalami pengembangan kernel Linux, pertimbangkan untuk menguasai bahasa pemrograman C terlebih dahulu.

Pengantar Singkat Bahasa Pemrograman C

Baca Selanjutnya

MembagikanMenciakMembagikanSurel

Topik-topik yang berkaitan

  • Linux
  • Memori Komputer
  • Kernel Linux

Tentang Penulis

Fatih Küçükkarakurt (7 Artikel Diterbitkan)

Seorang insinyur dan pengembang perangkat lunak yang merupakan penggemar matematika dan teknologi. Dia selalu menyukai komputer, matematika dan fisika. Dia telah mengembangkan proyek mesin permainan serta pembelajaran mesin, jaringan saraf tiruan dan perpustakaan aljabar linier. Selain itu terus bekerja pada pembelajaran mesin dan matriks linier.

More From Fatih Küçükkarakurt

Berlangganan newsletter kami

Bergabunglah dengan buletin kami untuk kiat teknologi, ulasan, ebook gratis, dan penawaran eksklusif!

Klik di sini untuk berlangganan