Teo de Raadt propozi që të përfshihet një mekanizëm i ri në OpenBSD për të reduktuar sipërfaqen e sulmit, i realizuar përmes zgjerimit të mundësive të thirrjes së sistemit openat. Patch-et me implementimin e flamujve shtesë për openat dhe open, të cilat kufizojnë mundësinë e kalimit në katalogët e lartë përmes "../" dhe qasjen në rrugët absolute, janë përgatitur për bërthamën, libc, si dhe disa aplikacione nga sistemi bazë. Ndryshimet ende nuk janë përfshirë në OpenBSD-current dhe janë në fazën e diskutimit mes zhvilluesve.
Familja e thirrjeve të sistemit openat(2) funksionon si një analog i open(2) me përjashtim të faktit se nëse parametri "path" tregon një rrugë relative, dosja e hapur përcaktohet në lidhje me katalogun që është i lidhur me përshkruesin e dosjes "fd", dhe jo në lidhje me katalogun aktual të punës. Nëse kaloni një rrugë absolute në openat, për shembull: int dirfd = open("/tmp", O_RDONLY | O_DIRECTORY); int hfd = openat(dirfd, "/etc/hosts", O_RDONLY);
funkcioni openat() do të injorojë "dirfd" dhe, si pasojë, rruga absolute do të përpunojë si zakonisht.
Prandaj, zëvendësimi i open() me openat() vetvetiu nuk rrit sigurinë e programit. Një thirrje e tillë mund të përshpejtojë analizën e rrugës, por nuk kufizon aksesin në sistemin e skedarëve. Flamujt që ndalojnë rrugët absolute (p.sh., RESOLVE_BENEATH dhe/ose RESOLVE_IN_ROOT për openat2 në Linux) nuk garantojnë mbrojtje: programuesi duhet t'i shtojë ato në të gjitha thirrjet përkatëse, dhe gjatë marrjes së kontrollit të procesit, një sulmues mund të përdorë rrugë të tjera për hapjen e skedarëve.
Gjatë punës mbi utilitarin openrsync, Teo kishte nevojë të kufizonte aftësitë e tij për të kaluar nëpër sistemin e skedarëve, por të bëhet kështu duke përdorur funksionet unveil() dhe pledge() ishte e pamundur. Atëherë lindi ideja për një mekanizëm si openat(), por me karakteristika sigurie që plotësojnë pledge/unveil ose madje funksionojnë në mungesë të tyre.
Ideja kryesore është të bësh kufizimet pjesë të vetë descriptor-it të katalogut. Për këtë, propozohet flamuri F_BELOW, i cili mund të vendoset përmes fcntl(), ose flamuri O_BELOW për open(). Një descriptor i limituar në këtë mënyrë "dirfd" do të lejojë vetëm kalime poshtë në pemën e katalogëve: thirrjet openat() me një rrugë absolute ose me kalime lart përmes ".." do të përfundojnë me gabim ENOENT. Në rastin e një sulmi që çon në ekzekutimin e kodit, tabela e descriptorëve të skedarëve të procesit do të përmbajë "dirfd" më pak funksionalë, duke kufizuar kështu sipërfaqen e sulmit.
Burimi: opennet.ru
