Apple'i insenerid teatasid, et nad on valmis testima Clangi kompilaatori 'âfbounds-safety' reĆŸiimi, mis tagab turvalise töötamise mĂ€llu mahtuvate andmete ĂŒle. ReĆŸiim on osa Apple'i toetatud LLVM hargnevast versioonist, mis on suunatud Swift projektile. Edaspidi on plaanis jĂ€rk-jĂ€rgult edastada 'âfbounds-safety' funktsionaalsus LLVM/Clangi pĂ”hikoodeksisse.
Teatatakse, et pakutud kaitsemehhanismi kasutatakse juba aktiivselt Apple'i toodetes, sealhulgas XNU tuumas, pĂŒsivarakoodides, heliraamatukogudes ja piltide dekooderites. 'âfbounds-safety' reĆŸiimi aktiveerimine vĂ€hendab rakenduste jĂ”udlust keskmiselt 5% (vahemikus -1% kuni 29%), suurendab koodi mahtu 9.1% (vahemikus -1.4% kuni 38%) ja aeglustab kompileerimist 11%.
'âfbounds-safety' reĆŸiimi kasutamine mĂ€lupiiride automaatseks tuvastamiseks, mis on seotud nĂ€idikuga, nĂ”uab koodi eriliste annotatsioonide lisamist ning 'ptrcheck.h' pĂ€ise kaasamist. Pakutud kaitsemeetodi sisu seisneb lubatud piiride jĂ€rgimise kontrollide automaatse lisamisega, mis pĂ”hinevad kĂ€sitsi mÀÀratud annotatsioonidel vĂ”i kompilatsioonile teadaolevatel suurustel.
Erinevalt laiendatud nĂ€idikute (wide pointer) kasutamisest, kus koos aadressiga on ka teavet puhvri ĂŒlemise ja alumise piiri kohta, 'âfbounds-safety' reĆŸiimi kasutamine ei riku ABI-d (rakenduse binaarliidest) ega muuda eksporditud nĂ€idikute formaati ning ei nĂ”ua kohe kogu projekti ĂŒmbertöötamist. 'âfbounds-safety' reĆŸiimis kasutatakse laiendatud nĂ€idikuid ainult piirkondades, mis ei ĂŒhti ABI-ga, samas kui ABI-d mĂ”jutavate nĂ€idikute puhul rakendatakse tavalisi nĂ€idikuid koos kontrollide asendamisega, mis pĂ”hinevad piireteave annotatsioonidel.
Annotatsioonid tuleb lisada struktuuride vĂ€ljade ja funktsioonide argumentide nĂ€idikutele, mis viitavad objektide massiivile, samuti globaalsed muutujad, kus on nĂ€idikud. Kohalike muutujate nĂ€idikute puhul annotatsioone lisama ei pea, kuna neid töödeldakse automaatselt kui laiendatud nĂ€idikuid, mis juba sisaldavad teavet lubatud piiride kohta. Koodistruktuuride kohta, mille puhul on vajalik annotatsioonide lisamine, vĂ€ljastab kompilaator teateid, kui see kĂ€ivitatakse 'âfbounds-safety' lipuga.
Mudeli kaitse, mis pĂ”hineb â-fbounds-safetyâ saab jĂ€rk-jĂ€rgult rakendada, failhaaval, katkestamata kogu projekti arendust. Kaitse lisamine projektile tĂ€hendab, et tuleb mĂ€rkida annotatsioonid kindlas koodifailis, kĂ”rvaldada kompilaatori hoiatused ja testida programmi toimimist, pĂ€rast mida neid etappe korratakse jĂ€rgmise faili jaoks. Kood, kuhu on lisatud annotatsioonid, jÀÀb ĂŒhilduv tava C-koodiga ja kompilaatoritega, mis ei toeta â-fbounds-safetyâ (kui kompileerida teiste kompilaatoritega vĂ”i ilma â-fbounds-safetyâ liputa, ei lisata tĂ€iendavaid piirikontrolle).
Programmi töö ajal, kui tuvastatakse juurdepÀÀs lubatust kaugemale, genereeritakse erand ja programm lĂ”petab oma toimimise. HĂ€daolukorra lĂ”petamine vĂ”ib samuti toimuda, kui on antud vale annotatsioon, seega â-fbounds-safetyâ kasutamisel on vajalik tĂ€iendav programmikatse.
Allolevas nĂ€ites on parameetrisse âint *pâ lisatud annotatsioon â__counted_by(n)â, mis lisab tĂ€iendava kontrolli lubatud piiride ĂŒle, mis kehtib kĂ€itamise ajal. Kui proovida kompileerida koodi â-fbounds-safetyâ reĆŸiimis ilma antud annotatsioonita, annab kompilaator mĂ€rku, et massiivi piiriinfo puudub vĂ€ljendi âp[i] = 0â töötlemisel. #include void init_buf(int *__counted_by(n) p, int n) { for (int i = 0; i < n; ++i) p[i] = 0; // reĆŸiimis â-fbounds-safetyâ lisab kompilaator ise kontrolli, mis on sarnane koodile âif (i = n) trap();â }
Kohalikest muutujatest, millel on nĂ€itajad, lisatakse kontrolle automaatselt, nĂ€iteks: void foo(int i){ char *buf = (char *)malloc(10); // nĂ€itaja bufi piires sĂ€ilitatakse teave piiride kohta buf[i] = 0xff; // lisatakse automaatselt kontroll âif (buf + i = buf + 10) trap();â }
Kompilaator proovib vĂ”imaluse korral optimeerida ja vĂ€listada liigsete koodide lisamise, kui koodis on juba vajalikud kontrollid. NĂ€iteks: for (size_t i = 0; i < count; ++i) { buf[i] = i; // kontroll âif (i = count) trap()â ei lisata, kuna ĂŒleval on juba tingimus âi < countâ ja i ei saa olla vĂ€iksem kui 0. }
Peamised annotatsioonid:
- â__counted_by(N)â â mÀÀrab puhvri suuruse siht tĂŒĂŒbi elementides.
- â__sized_by(N)â â mÀÀrab puhvri suuruse baitides.
- » __ended_by(P)» â mÀÀrab puhveri ĂŒlemise piiri.
- «__null_terminated» â arvestab null-sĂŒmbolit puhvri lĂ”ppena.
- «__single» â seob nĂ€itaja ĂŒhe objekti kĂŒlge. Kasutatakse vaikimisi ABI mĂ”jule alluvate nĂ€itajate puhul, kui eraldi mitte mÀÀrata annotatsiooni.
- «__bidi_indexable» â tĂ€iustatud nĂ€itaja, mis sisaldab teavet ĂŒlemiste ja alumiste piiride kohta. Kasutatakse vaikimisi ABI-le mittealluvate nĂ€itajate puhul.
- «__indexable» â tĂ€iustatud nĂ€itaja, mis sisaldab teavet ĂŒlemise piiri kohta.
- «__unsafe_indexable» â nĂ€itaja, mis ei kontrolli piireid (kooskĂ”las kaitsmata koodiga, nĂ€iteks nĂ€itajate saamiseks vĂ€liskoodist).
Allikas: opennet.ru
