Theo de Raadt navrhol začleniť do OpenBSD nový mechanizmus na zníženie plochy pre útok, ktorý by sa realizoval rozšírením systémového volania openat. Pre jadro, libc a niektoré aplikácie v základnom systéme boli pripravené záplaty implementujúce ďalšie príznaky pre openat a open, ktoré obmedzujú možnosť navigácie do vyšších adresárov pomocou "/." a prístupu k absolútnym cestám. Zmeny ešte neboli začlenené do OpenBSD-current a momentálne sa o nich diskutuje medzi vývojármi.
Rodina systémových volaní openat(2) sa správa ako open(2), s výnimkou, že ak je parameter „path“ relatívny, súbor, ktorý sa má otvoriť, je relatívny vzhľadom na adresár priradený k deskriptoru súboru „fd“, a nie k aktuálnemu pracovnému adresáru. Ak zadáte absolútnu cestu do openat, napríklad: int dirfd = open("/tmp", O_RDONLY | O_DIRECTORY); int hfd = openat(dirfd, "/etc/hosts", O_RDONLY);
Funkcia openat() bude ignorovať „dirfd“ a v dôsledku toho bude absolútna cesta spracovaná normálne.
Preto nahradenie funkcie open() funkciou openat() samo o sebe nezlepší bezpečnosť programu. Toto volanie môže zrýchliť analýzu cesty, ale neobmedzí prístup k súborovému systému. Príznaky, ktoré zakazujú absolútne cesty (napríklad RESOLVE_BENEATH a/alebo RESOLVE_IN_ROOT pre openat2 v Linux): programátor ich musí pridať do všetkých príslušných volaní a pri získaní kontroly nad procesom môže útočník použiť iné spôsoby otvárania súborov.
Počas práce na utilite openrsync potreboval Theo obmedziť jej možnosti prechádzania súborovým systémom, ale to nebolo možné pomocou funkcií unveil() a pledge(). Následne vymyslel mechanizmus podobný funkcii openat(), ale s bezpečnostnými funkciami, ktoré by dopĺňali funkcie pledge/unveil alebo by fungovali aj v ich neprítomnosti.
Základnou myšlienkou je urobiť obmedzenia súčasťou samotného deskriptora adresára. Na dosiahnutie tohto cieľa navrhujeme príznak F_BELOW, ktorý je možné nastaviť pomocou fcntl(), alebo príznak O_BELOW pre open(). Deskriptor „dirfd“ obmedzený týmto spôsobom povolí iba prechody smerom nadol v strome adresárov: volania openat() s absolútnou cestou alebo prechody smerom nahor cez „..“ zlyhajú s chybou ENOENT. V prípade útoku spustením kódu bude tabuľka deskriptorov súborov procesu obsahovať menej funkčných „dirfd“, čo obmedzí oblasť útoku.
Zdroj: opennet.ru
