Theo de Raadt foreslog at inkludere en ny mekanisme i OpenBSD for at reducere angrebsoverfladen, implementeret gennem en udvidelse af systemopkaldet openat. Patcher med implementeringen af ekstra flag for openat og open, der begrænser muligheden for at navigere til overordnede kataloger via "\/.." og adgangen til absolutte stier, er forberedt til kernen, libc, samt nogle applikationer fra basis-systemet. Ændringerne er endnu ikke inkluderet i OpenBSD-current og er under diskussion blandt udviklerne.
Familien af systemopkald openat(2) fungerer som et analog til open(2) med den undtagelse, at hvis den relative sti angivet i parameteren "path", så bestemmes den åbnede fil relativt til det katalog, der er knyttet til filbeskriveren "fd", og ikke til den nuværende arbejdsmappe. Hvis der sendes en absolut sti til openat, for eksempel: int dirfd = open("\/tmp", O_RDONLY | O_DIRECTORY); int hfd = openat(dirfd, "\/etc\/hosts", O_RDONLY);
Funktionen openat() vil ignorere "dirfd", og som følge heraf vil den absolutte sti blive behandlet normalt.
Derfor styrker en udskiftning af open() med openat() i sig selv ikke programmets sikkerhed. Et sådant opkald kan fremskynde sti-parse, men begrænser ikke adgangen til filsystemet. Flags, der forhindrer absolutte stier (for eksempel RESOLVE_BENEATH og\/eller RESOLVE_IN_ROOT for openat2 i Linux), garanterer ikke beskyttelse: programmøren skal tilføje dem til alle relevante opkald, og ved at overtage kontrollen over processen kan en angriber udnytte andre stier til at åbne filer.
Under arbejdet med værktøjet openrsync opstod der for Theo behovet for at begrænse dets muligheder for at navigere i filsystemet, men dette kunne ikke gøres ved hjælp af funktionerne unveil() og pledge(). Så kom ideen om en mekanisme, der ligner openat(), men med sikkerhedsegenskaber, der supplerer pledge\/unveil eller endda fungerer uden dem.
Hovedideen er at gøre begrænsninger til en del af selve katalogbeskriveren. Til dette formål foreslås flaget F_BELOW, som kan sættes via fcntl(), eller flaget O_BELOW til open(). Den på denne måde begrænsede beskrivelse "dirfd" vil kun tillade nedadgående bevægelser i katalogtræet: kald til openat() med absolutsti eller med bevægelse opad via ".." vil resultere i fejlen ENOENT. I tilfælde af et angreb, der fører til kodeeksekvering, vil processen's filbeskriver tabel indeholde mindre funktionelle "dirfd", hvilket vil begrænse angrebsfladen.
Kilde: opennet.ru
