Kiel parto de klopodoj plifortigi la sekurecon de kritikaj programaraj komponantoj de la platformo Android Google reskribis la pvmfm-firmvaron en Rust, kiu estas uzata por organizi la funkciadon de virtualaj maŝinoj lanĉitaj de la pVM-hipervizoro de la Android Virtualiga Kadro. Antaŭe, la firmvaro estis skribita en C kaj efektivigita sur la startigilo U-Boot, kies kodo antaŭe estis trovita enhavanta vundeblecojn kaŭzitajn de problemoj pri memoradministrado.
Firmvaro reverkita en Rust estas inkluzivita en la pakaĵo Android 14, kaj la universalaj bibliotekoj kreitaj dum la disvolviĝo de firmvaro estis pakitaj kiel kestaj pakaĵoj kaj donacitaj al la Rust-komunumo. Ekzemple, la pakaĵo smccc estis publikigita por subteni la interfacojn PSCI (Power State Coordination Interface) de ARM kaj la alvokojn SMCCC (SMC Calling Convention), same kiel la pakaĵon aarch64-paging por manipuli memorpaĝajn tabelojn. Laboro ankaŭ estis efektivigita por ripari cimojn kaj vastigi la funkciojn de la ekzistanta pakaĵo virtio-drivers per la efektivigo de VirtIO-peliloj. Aldone al la platformo Android La specifitaj pakaĵoj estas uzataj en la projekto Oak, kiu disvolvas komponantojn por sendi, konservi kaj prilabori datumojn en protektitaj medioj (TEE, Trusted Execution Environment).
La pVM-hipervizoro prenas kontrolon frue en la startprocezo kaj provizas plenan memorizolaĵon. virtualaj maŝinoj kaj la gastiganta medio, malhelpante la gastigan sistemon aliri protektitajn virtualajn maŝinojn kie sentemaj datumoj estas prilaborataj. La pvmfm (Protektita Virtuala Maŝina Firmvaro) firmvaro prenas kontrolon tuj post kiam la virtuala maŝino startas, kontrolas la kreitan medion, kaj decidas ĉu ĉesigi la startigon se integrecproblemoj estas detektitaj aŭ generas startigan atestilon por la gasta sistemo se la ĉeno de fido estas konfirmita.
Refaktorigo en Rust ebligas pli simplan kaj pli sekuran plenumon de la "regulo de du" uzata de Google por konservi la sekurecon de sistemkomponantoj. AndroidLaŭ ĉi tiu regulo, ĉiu aldonita kodo devas plenumi ne pli ol du el tri kondiĉoj: pritrakti nefidindajn enigajn datumojn, uzi nesekuran programlingvon (C/C++), kaj funkcii kun pli altaj privilegioj. Ĉi tiu regulo implicas, ke kodo por prilabori eksterajn datumojn devas esti aŭ reduktita al minimumaj privilegioj (izolita) aŭ skribita en sekura programlingvo. Laŭ statistikoj de Google, proksimume 70% de ĉiuj danĝeraj vundeblecoj identigitaj en Android, kaŭzita de eraroj dum laborado kun memoro.
Rust fokusiĝas al memorsekureco kaj reduktas la riskon de vundeblecoj kaŭzitaj de problemoj kiel uzo-post-liberigo kaj bufro-troŝarĝoj. Rust certigas memorsekurecon dum kompilado per referenckontrolado, spurado de objekta proprieto, kaj objekta vivdaŭro (ampleksa) kontado, same kiel per validigo de memoraliro dum rultempo. Rust ankaŭ provizas protekton kontraŭ entjeraj troŝarĝoj, postulas devigan inicialigon de variablovaloroj antaŭ uzo, pli bone traktas erarojn en la norma biblioteko, efektivigas la koncepton de neŝanĝeblaj referencoj kaj variabloj defaŭlte, kaj ofertas fortan statikan tajpadon por minimumigi logikajn erarojn.
Unu malfacilaĵo renkontata dum disvolvado de malaltnivelaj komponantoj kiel peliloj en Rust estas la bezono pritrakti nudajn montrilojn en nesekura reĝimo. Rust estas desegnita konsiderante program-asignitan memoron, dum kodo funkcianta sen aparataraj interkovroj devas aliri komunan memoron kaj MMIO. La kapabloj de Rust pritrakti nudajn montrilojn nuntempe lasas multe por deziri, sed tio devus pliboniĝi post kiam subteno por la makrooj offset_of, slice_ptr_get, kaj slice_ptr_len stabiliĝos.
Aliaj rimarkindaj mankoj inkluzivas la bezonon de plibonigita sintakso por aliri strukturajn kampojn kaj tabelajn indeksojn per simplaj montriloj sen krei referencojn, same kiel limigojn en kreado de sekuraj envolvaĵoj por nesekuraj operacioj, kiuj povas kaŭzi nedifinitan konduton kaj ne povas esti kontrolitaj de la kompililo. Ekzemple, tiajn envolvaĵojn ne eblas krei por operacioj kun memorpaĝaj tabeloj, ĉar paĝmapado en unu parto de la programo povas influi aliajn partojn.
Rilate al la rezulta kodgrandeco, la malnova pVM-firmvara versio okupis 220 KB, dum la nova okupis 460 KB. Tamen, la reskribita versio aldonis novajn funkciojn, kiuj permesis al ni forigi iujn aliajn komponantojn uzatajn dum la startigo. Rezulte, la tuta grandeco de ĉiuj malnovaj kaj novaj startigaj komponantoj estis komparebla. Rimarkinde, kiam grandeco estas pli grava ol rendimento, rezultoj kompareblaj al tiuj en C povas esti atingitaj per ebligado de pliaj grandec-optimumigaj reĝimoj en la kompililo, forigante nenecesajn dependecojn, kaj ne uzante ĉenformatajn ilojn.
Plie, ĝi mencias la daŭrigon de laboro pri la efektivigo de la kapablo funkciigi fidindajn aplikaĵojn (Trusted Application) skribitajn en la lingvo Rust en la operaciumo Trusty, kiu provizas TEE (Trusted Execution Environment) por Android, plenumita paralele kun Android sur la sama procesoro en aparta, izolita medio. Trusty estas uzata en Pixel-aparatoj kaj jam uzas Rust en bibliotekoj kaj sistemkomponantoj (la kerno restas en C).
fonto: opennet.ru
