Modernit käyttöjärjestelmät valvovat prosessien, tiedostojen, laitteiden ja käyttäjien välisiä turvallisuusrajoja. Tapa, jolla nämä rajat toteutetaan, vaihtelee kuitenkin merkittävästi järjestelmien suunnittelussa.

Useimmat valtavirran käyttöjärjestelmät nojaavat identiteettipohjaiseen pääsynhallintaan ja globaaleihin nimiavaruuksiin. Kyvykkyyspohjaiset käyttöjärjestelmät omaksuvat perustavanlaatuisesti toisen lähestymistavan: ne esittävät auktoriteetin eksplisiittisesti ja tekevät siitä ensiluokkaisen käsitteen.

Tämä kirjoitus esittelee kyvykkyysjärjestelmiä, selittää, miten ne eroavat perinteisistä ratkaisuista, ja hahmottelee, miksi ne ovat keskeisiä EriXin suunnittelulle.


Ongelma: ympäristöauktoriteetti

Perinteisissä järjestelmissä prosesseilla on usein pääsy resursseihin ympäristöauktoriteetin kautta.

Ympäristöauktoriteetti tarkoittaa, että ohjelma voi käyttää resurssia vain siksi, että se on olemassa jaetussa nimiavaruudessa ja järjestelmä katsoo ohjelmalla olevan lupa käyttää sitä.

Esimerkiksi:

  • Prosessi voi avata /etc/passwd-tiedoston, jos sillä on riittävät oikeudet.
  • Ohjelma voi muodostaa yhteyden verkkopistokkeeseen, jos käyttöjärjestelmä sallii sen.
  • Palvelu voi käyttää tiedostoja käyttäjäidentiteetin tai ryhmäjäsenyyden perusteella.

Kaikissa näissä tapauksissa auktoriteetti resurssin käyttöön on implisiittinen.

Prosessi ei pidä hallussaan suoraa, eksplisiittistä viittausta resurssiin. Sen sijaan se nojaa:

  • globaaleihin nimiin (tiedostopolut, portit, laitetunnisteet)
  • käyttöoikeustarkistuksiin (käyttäjätunnukset, oikeudet, ACL:t)

Tämä malli aiheuttaa useita ongelmia:

1. Confused Deputy -ongelma

Ohjelma voi vahingossa käyttää auktoriteettiaan väärin toisen ohjelman puolesta.

Esimerkiksi etuoikeutettu palvelu saattaa lukea tiedoston epäluotettavan asiakkaan pyynnöstä, vaikka asiakkaalla itsellään ei pitäisi olla siihen pääsyä.

2. Liian laaja auktoriteetti

Ohjelmat toimivat usein laajemmilla oikeuksilla kuin ne todellisuudessa tarvitsevat. Tämä kasvattaa virheiden tai kompromissien vaikutusta.

3. Vaikea analysoitavuus

On vaikea päätellä, mitä prosessi saa tehdä, ilman että analysoidaan globaalia tilaa, käyttäjäidentiteettejä ja pääsynhallintakäytäntöjä.


Ydinajatus: kyvykkyydet

Kyvykkyys on väärentämätön tunniste, joka antaa pääsyn tiettyyn objektiin tietyin oikeuksin.

Sen sijaan, että kysyttäisiin:

“Onko tällä prosessilla lupa käyttää tätä resurssia?”

kyvykkyyspohjainen järjestelmä kysyy:

“Omistaako tämä prosessi kyvykkyyden, joka valtuuttaa tämän operaation?”

Jos vastaus on ei, operaatiota ei voida suorittaa.


Kyvykkyyksien ominaisuudet

Kyvykkyyksillä on useita määrittäviä ominaisuuksia:

1. Väärentämättömyys

Prosessi ei voi luoda kelvollista kyvykkyyttä tyhjästä.

Kyvykkyydet luodaan ja niitä hallitaan ytimessä, mikä varmistaa, ettei niitä voi väärentää tai arvata.


2. Eksplisiittinen auktoriteetti

Kaikki auktoriteetti esitetään eksplisiittisesti kyvykkyyksien kautta.

Jos prosessi voi suorittaa operaation, sillä täytyy olla kyvykkyys, joka sallii sen. Globaaleista nimiavaruuksista ei tule implisiittistä pääsyä.


3. Hienojakoiset oikeudet

Kyvykkyydet voivat koodata tarkkoja käyttöoikeuksia, kuten:

  • vain luku -pääsy
  • kirjoitusoikeus
  • suoritusoikeus
  • rajatut osajoukot operaatioista

Tämä mahdollistaa tarkan hallinnan siitä, mitä kukin prosessi voi tehdä.


4. Siirrettävyys

Kyvykkyyksiä voidaan siirtää prosessien välillä, tavallisesti prosessien välisen viestinnän (IPC) kautta.

Tämä mahdollistaa auktoriteetin hallitun delegoinnin.


Objektit ja kyvykkyydet

Kyvykkyyspohjaisessa järjestelmässä kaikki mallinnetaan objektina:

  • muistialueet
  • tiedostot
  • laitteet
  • IPC-päätepisteet
  • prosessit

Kyvykkyys on viittaus objektiin yhdistettynä joukkoon oikeuksia.

Prosessi vuorovaikuttaa järjestelmän kanssa kutsumalla operaatioita objekteille kyvykkyyksiensä kautta.

Ytimessä ei tarvita globaaleja nimiä kuten tiedostopolkuja tai laitetunnisteita. Kaikki pääsy välitetään kyvykkyyksien kautta.


Miten kyvykkyysjärjestelmät toimivat

Yleisellä tasolla kyvykkyyspohjainen järjestelmä toimii näin:

  1. Ydin luo objektit ja kyvykkyydet.
  2. Jokaisella prosessilla on kyvykkyysavaruus (usein nimeltään CSpace), jossa sen kyvykkyydet säilytetään.
  3. Prosessi voi operoida vain niillä objekteilla, joihin sillä on kyvykkyydet.
  4. Kyvykkyyksiä voidaan siirtää prosessien välillä IPC:n kautta.
  5. Ydin pakottaa kaikki kyvykkyystarkistukset.

Tuloksena on järjestelmä, jossa auktoriteetti on:

  • eksplisiittinen
  • lokalisoitu
  • siirrettävä
  • helppo analysoida

Esimerkki: tiedoston avaaminen

Perinteinen malli

Perinteisessä järjestelmässä:

  1. Prosessi kutsuu open("/etc/config")
  2. Ydin tarkistaa oikeudet:
    • käyttäjätunnus
    • ryhmäjäsenyys
    • tiedoston tilabitit
  3. Jos pääsy sallitaan, palautetaan tiedostokuvaaja

Auktoriteetti tulee globaalista tilasta ja identiteetistä.


Kyvykkyyspohjainen malli

Kyvykkyysjärjestelmässä:

  1. Prosessilla täytyy jo olla tiedostokyvykkyys
  2. Se käyttää tätä kyvykkyyttä luku- tai kirjoitusoperaatioiden suorittamiseen

Jos prosessilla ei ole kyvykkyyttä, se ei voi käyttää tiedostoa riippumatta siitä, mitä nimeä se käyttää.

Ytimessä ei ole globaalia hakuvaihetta.


Delegointi ja vähimmät oikeudet

Yksi kyvykkyysjärjestelmien voimakkaimmista piirteistä on delegointi.

Prosessi voi antaa toiselle prosessille osajoukon auktoriteetistaan siirtämällä kyvykkyyden.

Esimerkiksi:

  • Tiedostopalvelin antaa asiakkaalle vain luku -oikeuden tiedostoon
  • Muistinhallinta myöntää pääsyn tiettyyn muistialueeseen
  • Prosessi antaa pääsyn IPC-päätepisteeseen

Tämä mahdollistaa vähimpien oikeuksien periaatteen:

Jokainen komponentti saa vain sen auktoriteetin, jota se todella tarvitsee.


Ympäristöauktoriteetin poistaminen

Kyvykkyysjärjestelmät poistavat ympäristöauktoriteetin kokonaan.

Niissä ei ole:

  • globaaleja nimiavaruuksia ytimessä
  • identiteettiin perustuvaa implisiittistä pääsyä
  • piilotettuja etuoikeuksia

Kaikki auktoriteetti on välitettävä eksplisiittisesti.

Tämä tekee paljon helpommaksi analysoida:

  • mitä prosessi voi tehdä
  • miten auktoriteetti virtaa järjestelmän läpi
  • missä mahdolliset turvallisuusongelmat voivat syntyä

Peruminen (vaikea ongelma)

Yksi kyvykkyysjärjestelmien haasteista on peruminen.

Kun kyvykkyys on annettu prosessille, miten se voidaan ottaa pois?

Eri järjestelmät toteuttavat perumisen eri tavoin:

  • epäsuorat tasot
  • viittausten seuranta
  • kyvykkyyspuut
  • versiointimekanismit

Peruminen on tärkeä tutkimusalue, ja siihen palataan EriXin myöhemmissä vaiheissa.


Kyvykkyysjärjestelmät käytännössä

Kyvykkyyspohjaiset ideat eivät ole uusia. Useat järjestelmät ovat toteuttaneet niitä:

  • KeyKOS / EROS
  • seL4 (formaalisti verifioitu mikroydin)
  • CHERI (laitteistotuetut kyvykkyydet)
  • Capsicum (FreeBSD:n kyvykkyyslaajennukset)

Nämä järjestelmät osoittavat, että kyvykkyyspohjaiset ratkaisut ovat sekä käytännöllisiä että voimakkaita.


Miten EriX käyttää kyvykkyyksiä

EriX on suunniteltu alusta asti kyvykkyyspohjaiseksi järjestelmäksi.

EriXissä:

  • kaikki auktoriteetti esitetään kyvykkyyksien kautta
  • kyvykkyydet ovat vahvasti tyypitettyjä
  • kyvykkyydet ovat muuttumattomia niiden luonnin jälkeen
  • kyvykkyydet siirretään IPC:n kautta
  • ydin pakottaa väärentämättömyyden ja turvallisuusinvariantit

Ytimessä ei ole globaaleja nimiavaruuksia. Kaikki resurssien käyttö välitetään kyvykkyyksien kautta.

Tämä on linjassa laajemman tavoitteen kanssa tehdä auktoriteetista:

  • eksplisiittinen
  • minimaalinen
  • helppo analysoida

Miksi tällä on merkitystä

Kyvykkyyspohjaiset järjestelmät tarjoavat perustan rakentaa:

  • turvallisempia järjestelmiä
  • modulaarisempia arkkitehtuureja
  • järjestelmiä, joita on helpompi analysoida ja verifioida

Poistamalla implisiittisen auktoriteetin ja tekemällä kaikesta pääsystä eksplisiittistä ne poistavat kokonaisia haavoittuvuusluokkia, jotka ovat yleisiä perinteisissä järjestelmissä.


Katse eteenpäin

Kyvykkyydet ovat EriXin perustava käsite. Tulevissa kirjoituksissa tarkastelemme, miten ne toteutetaan käytännössä, mukaan lukien:

  • kyvykkyysavaruudet (CSpace)
  • prosessien välinen viestintä (IPC)
  • muistinhallinta tyypittömien kyvykkyyksien avulla
  • delegointi ja auktoriteettigrafit

Kyvykkyyksien ymmärtäminen on ensimmäinen askel muun järjestelmän ymmärtämiseen.