Theo de Raadt foreslog at inkorporere en ny mekanisme i OpenBSD for at reducere angrebsfladen, implementeret ved at udvide openat-systemkaldet. Programrettelser, der implementerer yderligere flag for openat og open, hvilket begrænser muligheden for at navigere til øvre mapper via "/." og få adgang til absolutte stier, er blevet udarbejdet til kernen, libc og nogle applikationer i basissystemet. Ændringerne er endnu ikke blevet inkorporeret i OpenBSD-current og er i øjeblikket under diskussion blandt udviklere.
openat(2)-familien af systemkald opfører sig som open(2), bortset fra at hvis parameteren "path" er relativ, er den fil, der skal åbnes, relativ i forhold til den mappe, der er knyttet til filbeskrivelsen "fd", i stedet for den aktuelle arbejdsmappe. Hvis du sender 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 forbedrer det ikke i sig selv programsikkerheden at erstatte open() med openat(). Dette kald kan fremskynde stiparsing, men begrænser ikke adgangen til filsystemet. Flag, der forbyder absolutte stier (f.eks. RESOLVE_BENEATH og/eller RESOLVE_IN_ROOT for openat2 i Linux): programmøren skal tilføje dem til alle relevante kald, og når angriberen får kontrol over processen, kan vedkommende bruge andre måder at åbne filer på.
Mens han arbejdede på openrsync-værktøjet, var Theo nødt til at begrænse dets filsystemgennemgangsmuligheder, men dette var ikke muligt ved hjælp af funktionerne unveil() og pledge(). Han udtænkte derefter en mekanisme svarende til openat(), men med sikkerhedsfunktioner, der ville supplere pledge/unveil eller endda fungere i deres fravær.
Grundideen er at gøre begrænsningerne til en del af selve mappebeskrivelsen. For at opnå dette foreslår vi F_BELOW-flaget, som kan indstilles via fcntl(), eller O_BELOW-flaget for open(). En "dirfd"-beskrivelse, der er begrænset på denne måde, vil kun tillade nedadgående gennemgange i mappetræet: openat()-kald med en absolut sti eller opadgående gennemgange via ".." vil mislykkes med ENOENT-fejlen. I tilfælde af et kodeudførelsesangreb vil processens filbeskrivelsestabel indeholde færre funktionelle "dirfd"'er, hvilket begrænser angrebsfladen.
Kilde: opennet.ru
