Apple'i insenerid teatasid, et Clangi kompilaatori reĆŸiimi â-fbounds-safetyâ testimine on valmis, mis tagab turvalise töötamise C keeles koodiga. ReĆŸiim on osa Apple'i toetatavast LLVM harust, mis on mĂ”eldud Swift projekti jaoks. Tulevikus on plaanis jĂ€rk-jĂ€rgult funktsionaalsus â-fbounds-safetyâ ĂŒle kanda LLVM/Clangi pĂ”hikoodeksisse.
MĂ€rgitakse, et pakkunud kaitsemehhanismi rakendatakse juba aktiivselt Apple'i toodetes, nagu XNU tuum, pĂŒsivara, heliteekide ja piltide dekooderite puhul. ReĆŸiimi â-fbounds-safetyâ sisse lĂŒlitamine vĂ€hendab rakenduste jĂ”udlust keskmiselt 5% (ulatuses -1% kuni 29%), suurendab koodimahtu 9,1% (ulatuses -1,4% kuni 38%) ja aeglustab kompileerimist 11%.
ReĆŸiimi â-fbounds-safetyâ kasutamine, et automaatselt tuvastada mĂ€lu ala piiridest vĂ€ljumine, mis on seotud nĂ€idikuga, nĂ”uab koodi lisamist spetsiaalsete annotatsioonide ja pĂ€ise faili âptrcheck.hâ kaasamise. Pakutud kaitsemeetodi olemus seisneb automaatses kontrollide lisamises kehtivate piiride jĂ€rgimise osas, mis lisatakse kĂ€sitsi esitatud annotatsioonide vĂ”i kompilaatorile teada olevate suuruste alusel.
Erinevalt laienenud nĂ€idikute (wide pointer) kasutamisest, kus aadressi kĂ”rval on ka teave puhvri ĂŒlemise ja alumise piiri kohta, ei rikku reĆŸiim â-fbounds-safetyâ ABI-d (rakenduse binaarliidese), ei muuda eksporditud nĂ€idikute formaati ja ei nĂ”ua kogu projekti kohest ĂŒmbertegemist. ReĆŸiimis â-fbounds-safetyâ kasutatakse laienenud nĂ€idikuid ainult ABI-d mittehĂ”lmavates piirkondades, samas kui ABI-d mĂ”jutavate nĂ€idikute jaoks kasutatakse tavalisi nĂ€idikuid koos kontrollidega, mis on loodud piiride teabe anotatsioonide alusel.
Annotatsioonid tuleb siduda viidete kĂŒlge struktuuride ja funktsioonide parameetrites, mis viitavad objektide massiivile, samuti globaalsete muutuja viidete jaoks. Kohalikus muutuja viidete puhul ei ole annotatsiooni lisamine vajalik, kuna neid töödeldakse automaatselt kui laiendatud viiteid, mis juba sisaldavad teavet lubatud piiride kohta. Koodistruktuuride kohta, millele on vaja lisada annotatsioonid, annab kompilaator vihjeid, kui kĂ€ivitada koos lipuga "-fbounds-safety".
Mudel kaitse rakendamiseks pĂ”hineb â-fbounds-safetyâ saab jĂ€rk-jĂ€rgult juurutada, fail haaval, katkestamata kogu projekti arendust. Kaitsestruktuuri lisamine projekti seisneb annotatsioonide mÀÀramises konkreetses koodifailis, kompilaatori hoiatuste kĂ”rvaldamises ja programmi töö testimises, pĂ€rast mida neid samme korratakse jĂ€rgmise faili jaoks. Kood, kuhu on lisatud annotatsioonid, jÀÀb ĂŒhilduv tavapĂ€rase C-koodiga ja kompilaatoritega, mis ei toeta â-fbounds-safetyâ (kui koguda teiste kompilaatoritega vĂ”i ilma liputa â-fbounds-safetyâ, ei lisata lihtsalt tĂ€iendavaid piiri kontrollimist).
Programmi kĂ€igus, kui tuvastatakse ĂŒletamine lubatud piiridest, genereeritakse erand ja programm lĂ”petab oma töö. HĂ€daolukorra lĂ”petamine vĂ”ib samuti isegi toimuda vale annotatsiooni nĂ€itamise korral, mistĂ”ttu tuleks 'âfbounds-safety' kasutamisel lĂ€bi viia tĂ€iendav programmi testimine.
Allpool olevas nĂ€ites on parameetrisse 'int *p' lisatud annotatsioon '__counted_by(n)', mis lisab tĂ€iendava kontrolli lubatud piiride ĂŒle, mis kehtib töö ajal. Kui proovida kompileerida koodi reĆŸiimis 'âfbounds-safety' ilma selle annotatsioonita, annab kompilaator hoiatusi massiivi piiride teabe puudumise kohta 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' kompilaator lisab automaatselt kontrolli, mis sarnaneb koodiga 'if (i = n) trap();' }
Kohalikud muutujad seonduvad automaatselt kontrollide nÀidikute abil, nÀiteks: void foo(int i){ char *buf = (char *)malloc(10); /// buf nÀidiku jaoks salvestatakse piiride andmed buf[i] = 0xff; /// lisatakse automaatselt kontroll "if (buf + i = buf + 10) trap();" }
VĂ”imaluse korral optimiseerib kompilaator ja vĂ€listab liigsete koodide lisamise, kui koodis on juba vajalikud kontrollid. NĂ€iteks: for (size_t i = 0; i < count; ++i) { buf[i] = i; /// kontrolli "if (i = count) trap()" ei lisata, kuna ĂŒlal on juba tingimus "i < count" ja i ei saa olla vĂ€iksem kui 0. }
PÔhijoonised:
- «__counted_by(N)» â mÀÀrab mĂ€lu suuruse siht tĂŒĂŒbi elementides.
- «__sized_by(N)» â mÀÀrab mĂ€lu suuruse baitides.
- » __ended_by(P)» â mÀÀrab mĂ€lu ĂŒlemise piiri.
- «__null_terminated» â vĂ”tab arvesse nullikoodi kui mĂ”lema piiri lĂ”ppu.
- «__single» â seondub nĂ€idik ĂŒhele objektile. Rakendatakse vaikimisi ABI-d mĂ”jutavate nĂ€idikute puhul, kui annotatsiooni ei ole selgelt mÀÀratud.
- «__bidi_indexable» â tĂ€iustatud nĂ€itaja ĂŒlemiste ja alumiste piiride teabega. Rakendatakse vaikimisi nĂ€itajate jaoks, mis ei mĂ”juta ABI-d.
- «__indexable» â tĂ€iustatud nĂ€itaja ĂŒlemise piiri teabega.
- «__unsafe_indexable» â nĂ€itaja, mis ei kontrolli piire (ĂŒhilduv mitteprotected koodiga, nĂ€iteks nĂ€itajate hankimiseks vĂ€lisest koodist).
Allikas: opennet.ru
