Theo de Raadt predložio je uključivanje novog mehanizma u OpenBSD kako bi se smanjila površina za napad, implementirano proširenjem sistemskog poziva openat. Zakrpe koje implementiraju dodatne zastavice za openat i open, ograničavajući mogućnost navigacije do viših direktorija putem "/." i pristupa apsolutnim putanjama, pripremljene su za kernel, libc i neke aplikacije u osnovnom sustavu. Promjene još nisu uključene u OpenBSD-current i trenutno su u raspravi među programerima.
Obitelj sistemskih poziva openat(2) ponaša se kao open(2), osim što ako je parametar "path" relativan, datoteka koja se otvara je relativna u odnosu na direktorij povezan s deskriptorom datoteke "fd", a ne na trenutni radni direktorij. Ako openat-u proslijedite apsolutnu putanju, na primjer: int dirfd = open("/tmp", O_RDONLY | O_DIRECTORY); int hfd = openat(dirfd, "/etc/hosts", O_RDONLY);
Funkcija openat() će ignorirati "dirfd" i kao rezultat toga apsolutna putanja će se normalno obraditi.
Stoga, zamjena open() s openat() sama po sebi ne poboljšava sigurnost programa. Ovaj poziv može ubrzati parsiranje puta, ali ne ograničava pristup datotečnom sustavu. Zastavice koje zabranjuju apsolutne putanje (na primjer, RESOLVE_BENEATH i/ili RESOLVE_IN_ROOT za openat2 u Linux): programer ih mora dodati svim odgovarajućim pozivima, a prilikom preuzimanja kontrole nad procesom napadač može koristiti druge načine otvaranja datoteka.
Dok je radio na uslužnom programu openrsync, Theo je trebao ograničiti njegove mogućnosti prolaska kroz datotečni sustav, ali to nije bilo moguće pomoću funkcija unveil() i pledge(). Zatim je osmislio mehanizam sličan openat(), ali sa sigurnosnim značajkama koje bi nadopunjavale pledge/unveil ili čak radile u njihovoj odsutnosti.
Osnovna ideja je da ograničenja budu dio samog deskriptora direktorija. Da bismo to postigli, predlažemo zastavicu F_BELOW, koja se može postaviti putem fcntl(), ili zastavicu O_BELOW za open(). Deskriptor "dirfd" ograničen na ovaj način dopuštat će samo silazne prolaze u stablu direktorija: pozivi openat() s apsolutnom putanjom ili uzlazni prolazi putem ".." neće uspjeti s pogreškom ENOENT. U slučaju napada izvršenja koda, tablica deskriptora datoteka procesa sadržavat će manje funkcionalnih "dirfd"-ova, što ograničava površinu napada.
Izvor: opennet.ru
