Programiranje

Varnost in preveritelj razreda

V tem mesecu se nadaljuje razprava o varnostnem modelu Java, ki se je začela v avgustovskem "Under the Hood". V tem članku sem podal splošen pregled varnostnih mehanizmov, vgrajenih v navidezni stroj Java (JVM). Prav tako sem natančno preučil en vidik teh varnostnih mehanizmov: vgrajene varnostne funkcije JVM. V septembrskem "Under the Hood" sem preučil arhitekturo razrednega nakladalnika, še en vidik vgrajenih varnostnih mehanizmov JVM. Ta mesec se bom osredotočil na tretji del varnostne strategije JVM: preveritelj razreda.

Preverjevalnik datotek razreda

Vsak navidezni stroj Java ima preveritelj datotek razreda, ki zagotavlja, da imajo naložene datoteke razredov pravilno notranjo strukturo. Če preveritelj datoteke razreda odkrije težavo z datoteko razreda, vrže izjemo. Ker je datoteka razreda le zaporedje binarnih podatkov, navidezni stroj ne more vedeti, ali je določeno datoteko razreda ustvaril dobronamerni prevajalnik Java ali senčni krekerji, ki so bili prizadeti za ogrožanje integritete navideznega stroja. Posledično imajo vse izvedbe JVM preveritelj datotek razreda, ki ga je mogoče priklicati v nezaupljivih razredih, da se zagotovi, da so razredi varni za uporabo.

Eden od varnostnih ciljev, ki ga pomaga doseči preveritelj datotek razreda, je robustnost programa. Če je prevajalnik hroščev ali pametni razbijalnik ustvaril datoteko razreda, ki je vsebovala metodo, katere bajtode vsebujejo navodilo za preskok čez konec metode, bi ta metoda lahko, če bi bila poklicana, povzročila zrušitev navideznega stroja. Zato je zaradi robustnosti pomembno, da navidezni stroj preveri celovitost bajt kod, ki jih uvozi.

Čeprav se oblikovalci navideznih strojev Java lahko odločijo, kdaj bodo njihovi navidezni stroji izvedli ta preverjanja, bodo številne izvedbe največ preverjale takoj po nalaganju razreda. Tak navidezni stroj enkrat analizira bytecode (in preveri njihovo celovitost), preden se sploh izvedejo. Kot del preverjanja bajt kod navidezni stroj Java zagotavlja vsa navodila za preskok - na primer Pojdi do (vedno skoči), ifeq (preskok, če je vrh niza niza) itd. - povzroči preskok na drugo veljavno navodilo v toku bajtkode metode. Posledično navideznemu računalniku ni treba preverjati veljavnega cilja vsakič, ko naleti na navodilo za preskok, ko izvaja bajtkodne kode. V večini primerov je preverjanje vseh bajt kod enkrat, preden se izvedejo, učinkovitejši način za zagotovitev robustnosti kot preverjanje vsakega ukaza bajtkode vsakič, ko se izvede.

Preverjevalec datotek razreda, ki preverjanje opravi čim prej, najverjetneje deluje v dveh ločenih fazah. Med prvo fazo, ki poteka takoj po nalaganju razreda, preveritelj datoteke razreda preveri notranjo strukturo datoteke razreda, vključno s preverjanjem integritete bajt kod, ki jih vsebuje. Med drugo fazo, ki poteka med izvajanjem bajt kod, preveritelj datoteke razreda potrdi obstoj simbolično navedenih razredov, polj in metod.

Prva faza: Interni pregledi

Med prvo fazo preveritelj datoteke razreda preveri vse, kar je mogoče preveriti v datoteki razreda, tako da pogleda samo datoteko razreda (ne da bi pregledal druge razrede ali vmesnike). Prva faza preveritelja datoteke razreda zagotavlja, da je uvožena datoteka razreda pravilno oblikovana, notranje skladna, upošteva omejitve programskega jezika Java in vsebuje bajtode, ki bodo varne za izvajanje navideznega stroja Java. Če preveritelj datoteke razreda ugotovi, da kar koli od tega ni res, vrne napako in program nikoli ne uporabi datoteke razreda.

Preverjanje oblike in notranje skladnosti

Poleg preverjanja celovitosti bajt kod preveritelj med prvo fazo opravi tudi veliko preverjanj pravilne oblike zapisa razreda in notranje skladnosti. Na primer, vsaka datoteka predavanja se mora začeti z enakimi štirimi bajti, čarobno številko: 0xCAFEBABE. Namen čarobnih števil je, da razčlenjevalniki datotek olajšajo prepoznavanje določene vrste datotek. Torej, prva stvar, ki jo preveritelj datotek razreda verjetno preveri, je, da se uvožena datoteka zares začne 0xCAFEBABE.

Preverjevalnik datoteke razreda tudi preveri, ali datoteka razreda ni niti okrnjena niti izboljšana z dodatnimi zaključnimi bajti. Čeprav so lahko datoteke različnih razredov različno dolge, pa vsaka posamezna komponenta, ki je v datoteki razreda, označuje njeno dolžino in vrsto. Preveritelj lahko z vrstami in dolžinami komponent določi pravilno skupno dolžino za vsako posamezno datoteko razreda. Na ta način lahko preveri, ali ima uvožena datoteka dolžino, ki je skladna z njeno notranjo vsebino.

Preveritelj si ogleda tudi posamezne komponente, da se prepriča, ali gre za dobro oblikovane primerke njihove vrste komponente. Na primer, deskriptor metode (vrsta vrnitve metode ter število in tipi njenih parametrov) je shranjen v datoteki razreda kot niz, ki se mora držati določene slovnice brez konteksta. Eno od preverjanj, ki jih preveritelj opravi na posameznih komponentah, je zagotoviti, da je vsak deskriptor metode dobro oblikovan niz ustrezne slovnice.

Poleg tega preveritelj datotek razreda preveri, ali se razred drži določenih omejitev, ki mu jih nalaga specifikacija programskega jezika Java. Na primer, preveritelj uveljavi pravilo, da vsi razredi, razen razreda Predmet, mora imeti superrazred. Tako preveritelj datoteke razreda med izvajanjem preveri nekatera pravila jezika Java, ki bi jih bilo treba uveljaviti v času prevajanja. Ker preveritelj nikakor ne more vedeti, ali je datoteko razreda ustvaril dobronamerni prevajalnik brez napak, preveri vsako datoteko razreda, da se prepriča, ali se upoštevajo pravila.

$config[zx-auto] not found$config[zx-overlay] not found