Programmēšana

Drošība un klases verificētājs

Šī mēneša raksts turpina Java drošības modeļa diskusiju, kas sākta augusta "Zem pārsega". Šajā rakstā es sniedzu vispārēju pārskatu par Java virtuālajā mašīnā (JVM) iebūvētajiem drošības mehānismiem. Es arī cieši aplūkoju vienu no šiem drošības mehānismiem: JVM iebūvētās drošības funkcijas. Septembra “Zem pārsega” es apskatīju klases iekrāvēju arhitektūru, kas ir vēl viens JVM iebūvēto drošības mehānismu aspekts. Šomēnes es pievērsīšos JVM drošības stratēģijas trešajai daļai: klases verificētājam.

Klases faila verificētājs

Katrai Java virtuālajai mašīnai ir klases failu pārbaudītājs, kas nodrošina, ka ielādētajiem klases failiem ir pareiza iekšējā struktūra. Ja klases faila verificētājs atklāj problēmu ar klases failu, tas rada izņēmumu. Tā kā klases fails ir tikai bināro datu secība, virtuālā mašīna nevar uzzināt, vai konkrētu klases failu ir izveidojis labi domājošs Java kompilators vai ēnaini krekeri, kas ir pakļauti virtuālās mašīnas integritātes pārkāpšanai. Tā rezultātā visām JVM ieviešanām ir klases failu verificētājs, kuru var izsaukt neuzticamām klasēm, lai pārliecinātos, ka klases ir droši lietojamas.

Viens no drošības mērķiem, kuru klases failu pārbaudītājs palīdz sasniegt, ir programmas izturība. Ja kļūdains kompilators vai izveicīgs krekings radīja klases failu, kurā bija metode, kuras baitkodos bija norāde pāriet ārpus metodes beigām, šī metode, ja tā tiktu izsaukta, varētu izraisīt virtuālās mašīnas avāriju. Tādējādi noturības labad ir svarīgi, lai virtuālā mašīna pārbaudītu importēto baitkodu integritāti.

Lai gan Java virtuālo mašīnu dizaineriem ir atļauts izlemt, kad viņu virtuālās mašīnas veiks šīs pārbaudes, daudzas implementācijas visvairāk pārbaudīs tieši pēc klases ielādes. Šāda virtuālā mašīna vienreiz analizē baitkodus (un pārbauda to integritāti), pirms tie tiek izpildīti. Baitkodu pārbaudes ietvaros Java virtuālā mašīna pārliecinās par visām lēciena instrukcijām, piemēram, iet uz (lēkt vienmēr), ja vien (lēkt, ja kaudzes augšdaļa ir nulle) utt. - izraisiet lēcienu uz citu derīgu instrukciju metodes baitkodu plūsmā. Tā rezultātā virtuālajai mašīnai nav jāpārbauda derīgs mērķis katru reizi, kad tā sastopas ar lēciena instrukciju, izpildot baitkodus. Vairumā gadījumu visu baitkodu pārbaude vienreiz pirms to izpildes ir efektīvāks veids, kā garantēt robustumu, nekā katra baitkoda instrukcijas pārbaude katru reizi, kad tā tiek izpildīta.

Klases failu verificētājs, kurš pārbaudi veic pēc iespējas agrāk, visticamāk, darbojas divos atšķirīgos posmos. Pirmās fāzes laikā, kas notiek tieši pēc klases ielādes, klases faila verificētājs pārbauda klases faila iekšējo struktūru, ieskaitot tajā esošo baitkodu integritāti. Otrās fāzes laikā, kas notiek, kad tiek izpildīti baitkodi, klases faila verificētājs apstiprina simboliski atsaucīgu klašu, lauku un metožu esamību.

Pirmais posms: iekšējās pārbaudes

Pirmās fāzes laikā klases faila verificētājs pārbauda visu, ko iespējams pārbaudīt klases failā, apskatot tikai pašu klases failu (nepārbaudot citas klases vai saskarnes). Klases faila verificētāja pirmais posms nodrošina, ka importētais klases fails ir pareizi izveidots, iekšēji konsekvents, ievēro Java programmēšanas valodas ierobežojumus un satur baitkodus, kurus Java virtuālā mašīna varēs droši izpildīt. Ja klases faila verificētājs konstatē, ka kāds no šiem variantiem nav patiess, tas rada kļūdu, un klases fails programmu nekad neizmanto.

Pārbauda formātu un iekšējo konsekvenci

Papildus baitkodu integritātes pārbaudei verifikators pirmās fāzes laikā veic daudzas pārbaudes par pareizu klases faila formātu un iekšējo konsekvenci. Piemēram, katram klases failam jāsākas ar tiem pašiem četriem baitiem, burvju skaitli: 0xCAFEBABE. Burvju skaitļu mērķis ir atvieglot failu parsētājiem noteiktu failu veidu atpazīšanu. Tādējādi pirmais, ko klases failu pārbaudītājs, iespējams, pārbauda, ​​ir tas, ka importētais fails patiešām sākas ar 0xCAFEBABE.

Klases faila verificētājs arī pārbauda, ​​vai klases fails nav ne saīsināts, ne uzlabots, izmantojot papildu beigu baitus. Lai gan dažādi klases faili var būt dažāda garuma, katrs klases failā esošais atsevišķais komponents norāda tā garumu, kā arī veidu. Verificētājs var izmantot komponentu tipus un garumus, lai noteiktu pareizo kopējo garumu katram atsevišķam klases failam. Tādā veidā tā var pārbaudīt, vai importētā faila garums atbilst tā iekšējam saturam.

Verificētājs izskata arī atsevišķus komponentus, lai pārliecinātos, ka tie ir labi veidoti sava veida komponenti. Piemēram, metožu deskriptors (metodes atgriešanās veids un tā parametru skaits un veidi) tiek glabāts klases failā kā virkne, kurai jāievēro noteikta grama bez konteksta. Viena no pārbaudēm, ko verificētājs veic atsevišķiem komponentiem, ir pārliecināties, ka katra metodes deskriptors ir labi izveidota atbilstošās gramatikas virkne.

Turklāt klases faila verificētājs pārbauda, ​​vai klase pati ievēro noteiktus ierobežojumus, ko tai rada Java programmēšanas valodas specifikācija. Piemēram, verificētājs ievieš likumu, ka visām klasēm, izņemot klasi Objekts, jābūt superklasei. Tādējādi klases failu verificētājs izpildlaika laikā pārbauda dažus Java valodas noteikumus, kas būtu jāievieš kompilēšanas laikā. Tā kā verificētājam nav iespējas uzzināt, vai klases failu ir izveidojis labsirdīgs, bez kļūdām sastādītājs, tas pārbauda katru klases failu, lai pārliecinātos, vai tiek ievēroti noteikumi.

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