U računalima, da bi proces bio izvršan, potrebno ga je smjestiti u memoriju. Za to se procesu u memoriji mora dodijeliti polje. Dodjela memorije važno je pitanje kojeg treba biti svjestan, posebno u arhitekturi kernela i sustava.

Pogledajmo detaljno raspodjelu memorije u Linuxu i shvatimo što se događa iza kulisa.

Kako se vrši dodjela memorije?

Većina softverskih inženjera ne zna detalje ovog procesa. Ali ako ste kandidat za programera sustava, trebali biste znati više o tome. Gledajući proces dodjele, potrebno je ući u male detalje o Linuxu i glibc knjižnica.

Kada aplikacije trebaju memoriju, moraju je zatražiti od operativnog sustava. Ovaj zahtjev iz kernela će naravno zahtijevati sistemski poziv. Ne možete sami dodijeliti memoriju u korisničkom načinu rada.

The malloc() obitelj funkcija odgovorna je za dodjelu memorije u jeziku C. Ovdje se postavlja pitanje da li malloc(), kao glibc funkcija, vrši izravan poziv sustava.

U Linux kernelu ne postoji sistemski poziv koji se zove malloc. Međutim, postoje dva sistemska poziva za zahtjeve za memorijom aplikacija, a to su brk i mmap.

instagram viewer

Budući da ćete zahtijevati memoriju u svojoj aplikaciji putem glibc funkcija, možda se pitate koji od ovih poziva sustava glibc koristi u ovom trenutku. Odgovor je oboje.

Prvi poziv sustava: brk

Svaki proces ima susjedno polje podataka. Pozivom sustava brk povećava se vrijednost prekida programa, koja određuje granicu podatkovnog polja i izvodi se proces dodjele.

Iako je dodjela memorije ovom metodom vrlo brza, nije uvijek moguće vratiti neiskorišteni prostor u sustav.

Na primjer, uzmite u obzir da dodijelite pet polja, svako veličine 16 KB, uz brk sistemski poziv preko funkcije malloc(). Kada završite s brojem dva od ovih polja, nije moguće vratiti relevantni resurs (deallocation) kako bi ga sustav mogao koristiti. Jer ako smanjite vrijednost adrese da pokažete mjesto gdje počinje vaše polje broj dva, s pozivom na brk, izvršit ćete delokaciju za polja broj tri, četiri i pet.

Kako bi se spriječio gubitak memorije u ovom scenariju, malloc implementacija u glibc-u prati mjesta dodijeljena u polju podataka procesa i zatim specificira da se vrati u sustav s funkcijom free(), tako da sustav može koristiti slobodni prostor za daljnju memoriju izdvajanja.

Drugim riječima, nakon što se dodijeli pet područja od 16 KB, ako se drugo područje vrati s funkcijom free() i još jedno područje od 16 KB se nakon nekog vremena ponovno traži, umjesto povećanja područja podataka kroz brk sistemski poziv, vraća se prethodna adresa.

Međutim, ako je novozatraženo područje veće od 16 KB, tada će se podatkovno područje povećati dodjeljivanjem novog područja pozivom sustava brk budući da se područje dva ne može koristiti. Iako područje broj dva nije u upotrebi, aplikacija ga ne može koristiti zbog razlike u veličini. Zbog ovakvih scenarija dolazi do situacije koja se zove unutarnja fragmentacija, a zapravo rijetko možete iskoristiti sve dijelove memorije u potpunosti.

Za bolje razumijevanje, pokušajte sastaviti i pokrenuti sljedeći primjer aplikacije:

#uključiti <stdio.h>
#uključiti <stdlib.h>
#uključiti <unistd.h>
intglavni(int argc, čar* argv[])
{
čar *ptr[7];
int n;
printf("Pid od %s: %d", argv[0], getpid());
printf("Početni prekid programa: %p", sbrk (0));
za (n=0; n<5; n++) ptr[n] = malloc (16 * 1024);
printf("Nakon 5 x 16kB malloc: %p", sbrk (0));
besplatno(ptr[1]);
printf("Nakon oslobađanja od drugih 16kB: %p", sbrk (0));
ptr[5] = malloc (16 * 1024);
printf("Nakon dodjele 6. od 16 kB: %p", sbrk (0));
besplatno(ptr[5]);
printf("Nakon oslobađanja posljednjeg bloka: %p", sbrk (0));
ptr[6] = malloc (18 * 1024);
printf("Nakon dodjele novih 18 kB: %p", sbrk (0));
getchar();
povratak0;
}

Kada pokrenete aplikaciju, dobit ćete rezultat sličan sljedećem izlazu:

Pid od ./a.out: 31990
Početni program pauza: 0x55ebcadf4000
Nakon 5 x 16 kB malloc: 0x55ebcadf4000
Nakon oslobađanja od drugih 16 kB: 0x55ebcadf4000
Nakon dodjele 6. od 16 kB: 0x55ebcadf4000
Nakon oslobađanja posljednjeg bloka: 0x55ebcadf4000
Nakon dodjele a novi18kB: 0x55ebcadf4000

Izlaz za brk sa strace bit će sljedeći:

brk(NULL) = 0x5608595b6000
brk (0x5608595d7000) = 0x5608595d7000

Kao što vidiš, 0x21000 je dodan završnoj adresi podatkovnog polja. To možete razumjeti iz vrijednosti 0x5608595d7000. Tako otprilike 0x21000, ili je dodijeljeno 132 KB memorije.

Ovdje treba razmotriti dvije važne točke. Prvi je dodjela više od iznosa navedenog u uzorku koda. Drugi je koji je redak koda uzrokovao brk poziv koji je omogućio dodjelu.

Randomizacija rasporeda adresnog prostora: ASLR

Kada jedan za drugim pokrenete gornji primjer aplikacije, svaki put ćete vidjeti različite vrijednosti adrese. Nasumično mijenjanje adresnog prostora na ovaj način značajno komplicira rad sigurnosnih napada i povećava sigurnost softvera.

Međutim, u 32-bitnim arhitekturama, osam bitova se općenito koristi za nasumično raspoređivanje adresnog prostora. Povećanje broja bitova neće biti prikladno jer će adresabilno područje preko preostalih bitova biti vrlo malo. Također, korištenje samo 8-bitnih kombinacija ne otežava stvari dovoljno napadaču.

U 64-bitnim arhitekturama, s druge strane, budući da postoji previše bitova koji se mogu dodijeliti za ASLR rad, osigurava se mnogo veća slučajnost i povećava se stupanj sigurnosti.

Linux kernel također ima snagu Android uređaji a ASLR značajka je u potpunosti aktivirana na Androidu 4.0.3 i novijim verzijama. Čak i samo iz tog razloga, ne bi bilo pogrešno reći da 64-bitni pametni telefon pruža značajnu sigurnosnu prednost u odnosu na 32-bitne verzije.

Privremenim onemogućavanjem ASLR značajke sljedećom naredbom, čini se da prethodna testna aplikacija vraća iste vrijednosti adrese svaki put kada se pokrene:

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

Da biste ga vratili u prethodno stanje, bit će dovoljno upisati 2 umjesto 0 u istu datoteku.

Drugi poziv sustava: mmap

mmap je drugi sistemski poziv koji se koristi za dodjelu memorije na Linuxu. S pozivom mmap, slobodni prostor u bilo kojem području memorije preslikava se na adresni prostor pozivajućeg procesa.

U dodjeli memorije koja je napravljena na ovaj način, kada želite vratiti drugu particiju od 16 KB s funkcijom free() u prethodnom primjeru brk, ne postoji mehanizam koji bi spriječio ovu operaciju. Relevantni memorijski segment uklanja se iz adresnog prostora procesa. Označen je kao više ne korišten i vraćen u sustav.

Budući da su dodjele memorije s mmap-om vrlo spore u usporedbi s onima s brk-om, potrebna je brk alokacija.

S mmap-om se svako slobodno područje memorije preslikava na adresni prostor procesa, tako da se sadržaj dodijeljenog prostora resetira prije nego što se ovaj proces završi. Ako poništavanje nije izvršeno na ovaj način, podacima koji pripadaju procesu koji je prethodno koristio relevantno memorijsko područje također bi mogao pristupiti sljedeći nepovezani proces. Time bi bilo nemoguće govoriti o sigurnosti u sustavima.

Važnost dodjele memorije u Linuxu

Dodjela memorije je vrlo važna, posebno u optimizaciji i sigurnosnim pitanjima. Kao što se vidi u gornjim primjerima, nepotpuno razumijevanje ovog problema može značiti uništavanje sigurnosti vašeg sustava.

Čak i koncepti slični push i pop koji postoje u mnogim programskim jezicima temelje se na operacijama dodjele memorije. Biti u stanju koristiti i dobro ovladati sistemskom memorijom od vitalnog je značaja i za programiranje ugrađenog sustava i za razvoj sigurne i optimizirane arhitekture sustava.

Ako također želite uroniti svoje prste u razvoj jezgre Linuxa, prvo razmislite o svladavanju programskog jezika C.

Kratki uvod u programski jezik C

Pročitajte dalje

UdioCvrkutUdioE-mail

Povezane teme

  • Linux
  • Memorija računala
  • Linux kernel

O autoru

Fatih Küçükkarakurt (Objavljeno 7 članaka)

Inženjer i programer koji je ljubitelj matematike i tehnologije. Oduvijek je volio računala, matematiku i fiziku. Razvio je projekte motora za igre, kao i strojno učenje, umjetne neuronske mreže i biblioteke linearne algebre. Štoviše, nastavlja raditi na strojnom učenju i linearnim matricama.

Više od Fatiha Küçükkarakurta

Pretplatite se na naše obavijesti

Pridružite se našem biltenu za tehničke savjete, recenzije, besplatne e-knjige i ekskluzivne ponude!

Kliknite ovdje za pretplatu