Heap je osnovno mesto gde program može skladištiti podatke kada zahteva podatke pozivajući funkcije poput **`malloc`**, `calloc`... Osim toga, kada ti podaci više nisu potrebni, oni se oslobađaju pozivom funkcije **`free`**.
Kada se zahteva da se neki podatak skladišti u heap-u, određeni prostor heap-a se alocira za to. Taj prostor će pripadati binu i rezervisaće se samo za traženi podatak + prostor za zaglavlja binova + minimalno pomeranje veličine binova za blok. Cilj je rezervisati što manje memorije bez komplikovanja pronalaženja svakog bloka. Za to se koriste informacije o metapodacima bloka kako bi se znalo gde se nalazi svaki korišćeni/slobodan blok.
* Ako nema dovoljno prostora u heap-u da se alocira novi blok, menadžer heap-a traži od kernela da proširi memoriju alociranu za heap, a zatim koristi tu memoriju da generiše novi blok.
U **višenitnim** aplikacijama, menadžer heap-a mora sprečiti **trke za stanjem** koje bi mogle dovesti do rušenja. Početno je to bilo postignuto korišćenjem **globalne međusobne isključivosti** kako bi se osiguralo da samo jedna nit može pristupiti heap-u u isto vreme, ali to je uzrokovalo **probleme sa performansama** zbog uskog grla koje je prouzrokovala međusobna isključivost.
Da bi se to rešilo, ptmalloc2 allocator heap-a je uveo "arene", gde **svaka arena** deluje kao **zaseban heap** sa svojim **sopstvenim** podacima **strukture** i **međusobnom isključivošću**, omogućavajući više niti da obavljaju operacije heap-a bez mešanja, pod uslovom da koriste različite arene.
Podrazumevana "glavna" arena upravlja operacijama heap-a za aplikacije sa jednom niti. Kada se dodaju **nove niti**, menadžer heap-a im dodeljuje **sekundarne arene** kako bi smanjio sukob. Prvo pokušava da svaku novu nit poveže sa neiskorišćenom arenom, kreirajući nove ako je potrebno, do granice od 2 puta broja CPU jezgara za 32-bitne sisteme i 8 puta za 64-bitne sisteme. Kada se dostigne granica, **niti moraju deliti arene**, što može dovesti do potencijalnih sukoba.
Za razliku od glavne arene, koja se proširuje korišćenjem `brk` sistemskog poziva, sekundarne arene kreiraju "pod-heapove" korišćenjem `mmap` i `mprotect` kako bi simulirale ponašanje heap-a, omogućavajući fleksibilnost u upravljanju memorijom za višenitne operacije.
Pod-heapovi služe kao rezerve memorije za sekundarne arene u višenitnim aplikacijama, omogućavajući im da rastu i upravljaju svojim sopstvenim regionima heap-a odvojeno od glavnog heap-a. Evo kako se pod-heapovi razlikuju od početnog heap-a i kako funkcionišu:
* Kada menadžer heap-a kreira pod-heap, rezerviše veliki blok memorije kroz `mmap`. Ova rezervacija ne alocira memoriju odmah; jednostavno označava region koji druge sistemskih procesi ili alokacije ne bi trebali koristiti.
* Rezervisani memorijski region je prvobitno označen kao `PROT_NONE`, što znači da kernel ne mora alocirati fizičku memoriju za ovaj prostor još.
* Da bi "proširio" pod-heap, menadžer heap-a koristi `mprotect` da promeni dozvole stranica sa `PROT_NONE` na `PROT_READ | PROT_WRITE`, što podstiče kernel da alocira fizičku memoriju na prethodno rezervisane adrese. Ovaj postepeni pristup omogućava pod-heapu da se proširi po potrebi.
*`mchunkptr bins[NBINS * 2 - 2];` sadrži **pokazivače** na **prvi i poslednji blokove** malih, velikih i nesortiranih **binova** (-2 je zato što se indeks 0 ne koristi)
* Stoga, **prvi blok** ovih binova će imati **pokazivač unazad na ovu strukturu** i **poslednji blok** ovih binova će imati **pokazivač unapred** na ovu strukturu. Što u osnovi znači da ako možete **procureti ove adrese u glavnoj areni** imaćete pokazivač na strukturu u **libc-u**.
* Strukture `struct malloc_state *next;` i `struct malloc_state *next_free;` su povezane liste arena
* Blok `top` je poslednji "blok", koji je u osnovi **sav preostali prostor heap-a**. Kada je top blok "prazan", heap je potpuno iskorišćen i potrebno je zatražiti više prostora.
* Blok `last reminder` dolazi iz slučajeva kada nije dostupan tačno određen blok veličine i stoga se veći blok deli, a preostali deo pokazivača se smešta ovde.
```c
// From https://heap-exploitation.dhavalkapil.com/diving_into_glibc_heap/malloc_state
struct malloc_state
{
/* Serialize access. */
__libc_lock_define (, mutex);
/* Flags (formerly in max_fast). */
int flags;
/* Fastbins */
mfastbinptr fastbinsY[NFASTBINS];
/* Base of the topmost chunk -- not otherwise kept in a bin */
mchunkptr top;
/* The remainder from the most recent split of a small request */
mchunkptr last_remainder;
/* Normal bins packed as described above */
mchunkptr bins[NBINS * 2 - 2];
/* Bitmap of bins */
unsigned int binmap[BINMAPSIZE];
/* Linked list */
struct malloc_state *next;
/* Linked list for free arenas. Access to this field is serialized
by free_list_lock in arena.c. */
struct malloc_state *next_free;
/* Number of threads attached to this arena. 0 if the arena is on
the free list. Access to this field is serialized by
free_list_lock in arena.c. */
INTERNAL_SIZE_T attached_threads;
/* Memory allocated from the system in this arena. */
Zatim, prostor za korisničke podatke, i na kraju 0x08B da označi veličinu prethodnog dela kada je deo dostupan (ili za skladištenje korisničkih podataka kada je alociran).
Moguće je videti da je string panda sačuvan na `0xaaaaaaac12a0` (što je adresa data kao odgovor od strane malloc unutar `x0`). Proveravajući 0x10 bajtova pre toga, moguće je videti da `0x0` predstavlja da **prethodni blok nije korišćen** (dužina 0) i da je dužina ovog bloka `0x21`.
Dodatni prostor rezervisan (0x21-0x10=0x11) dolazi od **dodatnih zaglavlja** (0x10) i 0x1 ne znači da je rezervisano 0x21B već poslednja 3 bita dužine trenutnog zaglavlja imaju neka posebna značenja. Pošto je dužina uvek poravnata na granicu od 16 bajtova (na 64-bitnim mašinama), ovi bitovi zapravo nikada neće biti korišćeni od strane broja dužine.
```
0x1: Previous in Use - Specifies that the chunk before it in memory is in use
0x2: Is MMAPPED - Specifies that the chunk was obtained with mmap()
0x4: Non Main Arena - Specifies that the chunk was obtained from outside of the main arena