Sanitajzeri Flashcards
Stack smashing
Pojava da mozemo da predefinisemo izlazni pokazivac iz stek okvira I da
skocimo na bilo sta I onda se nece nastaviti izvrsavanje funkcija koje se nalaze “ispod” , tj. nece se vratiti na njih.
Stek katanac (stek kanarinac)
pored pokazivaca gde treba da se vratimo se nalazi neka vrednost
(na pocetku je to neka nasumicna vrednost) I prilikom izlaska iz funkcije ce se proveravati da li se
ta neka nasumicna vrednost promenila ili nije. Ako je vrednost promenila, OS “ubija” nas
program, ako se vrednost nije promenila sve ok.
Shadow stack
– ili drzimo sve bitne informacije kopirane na jos jednom mestu (iz steka) ili samo
neke glavne, najbitnije informacije kloniramo na pomocni stek. Prednost je sto posle nekih funkcija mozemo da proverimo da li se stvari razlikuju na glavnom steku I shadow steku. Ako se razlikuju, “ubijamo” program, a ako se bitne stvari ne razlikuju program nastavlja sa izvrsavanjem (sve sto cuvamo na tom shadow steku nije kopirano (da ne bi dodatno zauzimalo memoriju) vec se cuva u vidu pokazivaca). Znaci, pored glavne memorije imamo shadow memory kao nekakav
klon glavne, koji cuva samo bitne infomacije koje posle mozemo da koristimo.
Address Sanitizer (ASAN)
Pozivamo ga tako sto u Makefile-u ukljucimo fleg: -fsanitize=address za kompajliranje i linkovanje.
Koristi se da bi se detektovale greske kao sto su use after free, index out of bounds, kada pokusamo da pristupimo memoriji koju smo ranije npr. inicijalizovali u nekoj funkciji ali ne na hipu vec na steku pa smo zavrsili rad te funkcije i presli na drugu.
Ideja je da shadow memorija mapira originalnu memoriju samo umesto stvarnog sadrzaja, shadow memorija oznacava da li je celija validna ili nevalidna. Crvenom ce da oznacava odredjeni broj celija post-alocirane memorije I pre-alocirane memorije. I onda kada neko za neki blok memorije zatrazi prostor, nece uzimati zeleni deo naravno, ali ni crveni. Ti crveni delovi oko zelenog dela nazivaju se poison memory. Kada se pozove free, oslobadja se originalna memorija, a u shadow memoriji se taj deo oznacava nekom novom bojom, ali svakako ostaje poison. Malloc
mora da izbegava blokove memorije koji su skoro bili oslobodjeni, tj. da se trudi da njih sto kasnije iskoristi jer ako dodje do baga use after free, ne bi se taj bag detektovao jer bi na toj lokaciji bilo nesto drugo.
U praksi se za svaki red od 8 bajtova iz originalne memorije, u shadow memoriji pamti samo 1 bajt u koji se smesta vrednost promenljive i (i-ti red originalne memorije). Znaci, shadow memorija ce biti 8 puta manja od originalne memorije.
Zameni normalne operacije malloc I free nekim drugacijim I dobijemo dosta dobre provere za vecinu problematicnih situacija koje mozemo da imamo sa dinamickom ili statickom memorijom.
Zasto se sanitajzeri ne ukljucuju u zavrsni projekat
Kompajler usporava izvrsavanje programa time sto svaki put radi proveru da li je memorija kojoj zelimo da pristupimo poison ili ne
Thread sanitizer (TSAN)
Pozivamo ga tako sto u Makefile-u ukljucimo fleg: -fsanitize=thread za kompajliranje i linkovanje.
Koristi se da bi se uocili neki race condition-i (dead lock, data race…).
U ovom slucaju postoji za skoro svaku nit posebna shadow memorija (celija) koja cuva:
1) TID (thread identifier)
2) vremenska oznaka kada je nit pokusala da pristupi odredjenom bitu u memoriji
3) flegove kojim tacno bajtovima je nit pokusala da pristupi
4) jedan bit koji govori da li je read ili write (r/w)
Za svakih 8 bajtova u originalnom memoriji ce biti 4 takve shadow celije
Kada neka nit pokusa da pristupi odredjenom delu u memoriji kompajler ce da generise dodatne instrukcije da rade jos nesto I proveravace da li niti zele da
pristupe istim delovima memorije (preko 3) stavke proverava da li postoji preklapanje) takodje gleda preko stavke 4) da li niti zele da pisu ili citaju. Kada se na taj nacin detektuju kolizije (potencijalni bagovi) potrebno je proveriti dodatne inf u vezi katanaca (da li su ti delovi memorije bili zakljucani, da li su stvari sinhronizovane kako treba ili ne).
Koristi se znacajno vise memorije u odnosu na address sanitizer, a
takodje I daje vece usporenje programu
Memory sanitizer (MSAN)
Pozivamo ga tako sto u Makefile-u ukljucimo fleg: -fsanitize=memory za kompajliranje i linkovanje.
Ima zadatak da detektuje da li pristupamo (u smislu citamo) memoriji koja nije inicijalizovana.
Shadow memorija moze da bude bit maska sta je inicijalizovano u glavnom memoriji (1) a sta nije (0). Ako pokusamo da pristupimo tim zelenim flegovima (tj. jedinicama) onda nam shadow memorija kaze da je sve ok, a crvenim (tj. nulama) “ubijamo” program. Pamtimo za svaki bit a ne bajt zbog bitovskih operacija (zato sto moze biti a = a | 00100), a drugi razlog je sto mozemo da kazemo int a:2 (a je 2 bita), int b:4, int c:2 i onda ce kompajler ta 3 da zapakuje u 1 bajt, a neka od tih promenljivih moze da bude inicijalizovana a neka ne.
Problem sa MSAN-om je sto kada deklarisemo neku strukturu koja se sastoji od char-ova I int-ova, a posto se u memoriji radi poravnjanje na 8 bajtova, kada stavimo char ostaje neiskorisceni prostor I onda kompajler mora da zna da taj deo memorije
nije bag vec tako treba.