Teo de Raadt predložio je uključivanje novog mehanizma u OpenBSD za smanjenje površine napada, implementiranog kroz proširenje mogućnosti sistemskog poziva openat. Zak patches s implementacijom dodatnih zastavica za openat i open, koje ograničavaju mogućnost prelaska u gornje direktorije putem "\/.." i pristupanja putem apsolutnih putanja, pripremljeni su za kernel, libc, kao i neka aplikacija iz osnovnog sistema. Promjene još nisu uključene u OpenBSD-current i trenutno su u fazi rasprave među programerima.
Obitelj sistemskih poziva openat(2) djeluje kao analog open(2) osim što, ako je u parametru "path" navedena relativna putanja, tada se otvarana datoteka određuje u odnosu na direktorij povezan s datotečnim opisnikom "fd", a ne u odnosu na trenutni radni direktorij. Ako se proslijedi apsolutna putanja u openat, na primjer: int dirfd = open("\/tmp", O_RDONLY | O_DIRECTORY); int hfd = openat(dirfd, "\/etc\/hosts", O_RDONLY);
Funkcija openat() ignorirat će "dirfd" i, kao posljedicu, apsolutna putanja će se obraditi na uobičajen način.
Stoga sama zamjena open() s openat() ne poboljšava sigurnost programa. Takav poziv može ubrzati analizu putanje, ali ne ograničava pristup datotečnom sustavu. Ni zastavice koje zabranjuju apsolutne putanje (npr. RESOLVE_BENEATH i\/ili RESOLVE_IN_ROOT za openat2 u Linuxu) ne jamče zaštitu: programer ih mora dodati svim odgovarajućim pozivima, a u slučaju preuzimanja kontrole nad procesom, napadač može iskoristiti druge mogućnosti otvaranja datoteka.
Tijekom rada na alatu openrsync, Teo je imao potrebu ograničiti njegove mogućnosti za prolazak kroz datotečni sustav, ali to nije bilo moguće ostvariti pomoću funkcija unveil() i pledge(). Tada se pojavila ideja o mehanizmu sličnom openat(), ali s sigurnosnim svojstvima koja dopunjuju pledge\/unveil ili čak funkcioniraju bez njih.
Osnovna ideja je učiniti ograničenja dijelom samog deskriptora direktorija. U tu svrhu predlaže se zastavica F_BELOW, koja se može postaviti putem fcntl(), ili zastavica O_BELOW za open(). Ograničeni na ovaj način deskriptor „dirfd“ dopuštat će samo prijelaze prema dolje po stablu direktorija: pozivi openat() s apsolutnom putanjom ili s prijelazom prema gore putem „..“ završavat će s greškom ENOENT. U slučaju napada koji dovodi do izvršenja koda, tablica datotečnih deskriptora procesa sadržavat će manje funkcionalne „dirfd“, što će ograničiti površinu napada.
Izvor: opennet.ru
