Theo de Raadt ehdotti uuden mekanismin sisällyttämistä OpenBSD:hen hyökkäyspinnan pienentämiseksi. Tämä mekanismi toteutettaisiin laajentamalla openat-järjestelmäkutsua. Kerneliin, libc:hen ja joillekin perusjärjestelmän sovelluksille on valmisteltu korjauspäivityksiä, jotka toteuttavat lisälippuja openatille ja openille, rajoittaen mahdollisuutta siirtyä ylempiin hakemistoihin "/."-viivojen kautta ja absoluuttisten polkujen käyttöä. Muutoksia ei ole vielä sisällytetty OpenBSD-currentiin, ja niistä keskustellaan parhaillaan kehittäjien kesken.
openat(2)-järjestelmäkutsuperhe toimii kuten open(2), paitsi että jos "path"-parametri on suhteellinen, avattava tiedosto on suhteellinen tiedoston kuvaajaan "fd" liittyvään hakemistoon eikä nykyiseen työhakemistoon nähden. Jos annat openat-kutsulle absoluuttisen polun, esimerkiksi: int dirfd = open("/tmp", O_RDONLY | O_DIRECTORY); int hfd = openat(dirfd, "/etc/hosts", O_RDONLY);
openat()-funktio jättää "dirfd":n huomiotta ja sen seurauksena absoluuttinen polku käsitellään normaalisti.
Siksi open():n korvaaminen openat():lla ei sinänsä paranna ohjelman tietoturvaa. Tämä kutsu voi nopeuttaa polun jäsentämistä, mutta ei rajoita pääsyä tiedostojärjestelmään. Lipuja, jotka estävät absoluuttiset polut (esimerkiksi RESOLVE_BENEATH ja/tai RESOLVE_IN_ROOT openat2:lle Linux): ohjelmoijan on lisättävä ne kaikkiin asianmukaisiin kutsuihin, ja prosessin hallinnan saadessaan hyökkääjä voi käyttää muita tapoja avata tiedostoja.
Työskennellessään openrsync-apuohjelman parissa Theon piti rajoittaa sen tiedostojärjestelmän läpikulkuominaisuuksia, mutta tämä ei ollut mahdollista unveil()- ja pledge()-funktioilla. Sitten hän kehitti openat()-funktion kaltaisen mekanismin, mutta siinä olisi turvaominaisuuksia, jotka täydentäisivät pledge/unveil-funktioita tai jopa toimisivat ilman niitä.
Perusajatuksena on tehdä rajoituksista osa itse hakemistodeskriptoria. Tämän saavuttamiseksi ehdotamme F_BELOW-lippua, joka voidaan asettaa fcntl():n kautta, tai O_BELOW-lippua open():lle. Tällä tavoin rajoitettu "dirfd"-deskriptori sallii vain alaspäin suuntautuvat läpikulut hakemistopuussa: openat()-kutsut absoluuttisella polulla tai ylöspäin suuntautuvat läpikulut ".."-merkillä epäonnistuvat ENOENT-virheellä. Koodin suoritushyökkäyksen sattuessa prosessin tiedostodeskriptoritaulukko sisältää vähemmän toiminnallisia "dirfd"-lippuja, mikä rajoittaa hyökkäyspinta-alaa.
Lähde: opennet.ru
