Sebuah layanan dapat memvalidasi pathname tetapi tetap membuka objek yang berbeda jika namespace berubah antara validasi dan pemakaian. Symbolic link, topologi mount, operasi rename, dan link khusus procfs membuat resolusi pathname menjadi operasi kernel dengan state yang dapat berubah secara konkuren. Linux openat2() menangani sebagian batas ini dengan melekatkan batasan resolusi pada lookup yang menghasilkan file descriptor.

Properti keamanannya lebih sempit daripada sanitasi path secara umum. openat2() tidak menyatakan bahwa sebuah pathname aman. Syscall ini memungkinkan pemanggil meminta kernel menolak perilaku resolusi tertentu saat kernel menjalankan path walk.

Kebijakan resolusi menyatu dengan operasi open

openat2() menerima struktur open_how yang memuat flag open biasa serta field resolve. Sebuah pemanggilan dapat menambatkan path relatif pada directory file descriptor dan menerapkan batasan dalam operasi kernel yang sama:

struct open_how how = {
    .flags = O_RDONLY | O_CLOEXEC,
    .resolve = RESOLVE_BENEATH | RESOLVE_NO_MAGICLINKS,
};

int fd = syscall(SYS_openat2, dirfd, path, &how, sizeof(how));

RESOLVE_BENEATH menolak resolusi yang keluar ke atas direktori yang diberikan melalui komponen seperti .. atau melalui resolusi path absolut. Flag ini saat ini juga menonaktifkan resolusi magic link. Antarmuka terdokumentasi menyarankan RESOLVE_NO_MAGICLINKS dinyatakan secara eksplisit jika properti tersebut diperlukan, bukan bergantung pada implikasi yang berlaku saat ini.

Susunan ini menghapus pemisahan umum antara pemeriksaan userspace dan open yang dilakukan kemudian. Pathname masih dapat berpacu dengan perubahan namespace, tetapi kondisi resolusi yang diminta dievaluasi kernel selama operasi yang mengembalikan descriptor.

RESOLVE_IN_ROOT mengubah root lookup untuk satu operasi

RESOLVE_IN_ROOT memperlakukan direktori yang dirujuk dirfd sebagai root resolusi pathname selama pemanggilan tersebut. Path absolut ditafsirkan relatif terhadap direktori itu, dan symbolic link absolut ditangani relatif terhadap root sementara yang sama. Komponen .. pada root tidak dapat keluar darinya.

Perilaku ini menyerupai sebagian semantik resolusi path milik chroot() tanpa mengubah root directory proses. Ini adalah aturan lookup yang berlaku untuk satu operasi, bukan jail filesystem pada seluruh proses. File descriptor yang sudah dimiliki proses tetap dapat digunakan sesuai izinnya, dan syscall lain tidak otomatis dibatasi oleh flag ini.

RESOLVE_BENEATH dan RESOLVE_IN_ROOT menyatakan kebijakan berbeda dan tidak ditujukan untuk digabungkan. Pemanggil perlu memilih model yang sesuai dengan kontrak pathname, bukan memperlakukan semua resolve flag sebagai hardening yang selalu aditif.

RESOLVE_NO_SYMLINKS menolak resolusi symbolic link pada setiap komponen pathname. Flag ini juga mengimplikasikan efek RESOLVE_NO_MAGICLINKS. Perilakunya lebih ketat daripada hanya menolak symbolic link terakhir dengan flag seperti O_NOFOLLOW, karena komponen perantara juga tercakup.

RESOLVE_NO_MAGICLINKS menargetkan magic link kernel seperti entri tertentu yang diekspos procfs. Objek tersebut dapat memiliki semantik di luar symbolic link biasa, termasuk referensi ke objek yang dipegang kernel. Pemblokiran magic link sambil tetap mengizinkan symbolic link biasa karena itu dapat menjadi kebijakan tersendiri.

Layanan yang mengizinkan symlink di dalam tree terkelola dapat memilih RESOLVE_BENEATH dengan pembatasan magic link secara eksplisit. Layanan yang model objeknya melarang symlink sepenuhnya dapat meminta RESOLVE_NO_SYMLINKS. Batasan yang tepat mengikuti semantik namespace yang memang hendak diekspos aplikasi.

Perpindahan mount membentuk batas kepercayaan lain

RESOLVE_NO_XDEV menolak traversal melintasi mount point, termasuk bind mount. Aturan ini dapat mencegah path walk memasuki filesystem yang di-mount di bawah tree direktori yang semula diterima.

Batasan tersebut kuat secara operasional. Hierarki direktori yang sah dapat memuat mount point, dan bind mount lazim pada tata letak runtime terisolasi. Mengaktifkan flag ini karena itu mengubah struktur namespace yang dapat dijangkau; flag tersebut bukan opsi validasi tanpa konsekuensi.

Pembatasan mount juga tidak menggantikan otorisasi objek. Kemampuan mencapai file tanpa melintasi mount tidak menyatakan bahwa pemanggil semestinya memperoleh file tersebut. Pemeriksaan DAC, capability, dan Linux Security Module tetap berlaku sesuai kondisi masing-masing.

Resolusi cache menukar kelengkapan dengan kondisi lookup nonblocking

RESOLVE_CACHED meminta kernel menyelesaikan resolusi menggunakan data lookup yang sudah berada di cache tanpa I/O atau revalidasi filesystem yang mengharuskan keluar dari fast path. Jika kondisi itu tidak dapat dipenuhi, pemanggilan dapat gagal dengan EAGAIN sehingga aplikasi dapat mencoba kembali tanpa flag tersebut atau mendelegasikan operasi ke tempat lain.

Flag ini terutama merupakan batas eksekusi lookup, bukan primitif confinement. Keberadaan pathname di cache tidak boleh ditafsirkan sebagai bukti bahwa path tersebut lebih tepercaya. Kebijakan keamanan tetap berasal dari aturan resolusi lain serta pemeriksaan izin biasa pada lookup yang dihasilkan.

Descriptor hasil open menjadi keluaran tahan lama dari path walk

Keuntungan arsitektural utama muncul setelah resolusi berhasil. Kode dapat melakukan operasi berikutnya melalui file descriptor yang dikembalikan, alih-alih membangun ulang otoritas dari pathname awal. Descriptor merujuk objek yang telah dibuka meski nama pada direktori di sekitarnya kemudian diubah melalui rename.

Hal tersebut tidak membuat semua operasi berikutnya bebas race. Aplikasi yang membuka ulang nama child, membentuk path baru, atau mengambil keputusan otorisasi dari metadata yang dapat berubah menciptakan batas tambahan. openat2() membatasi satu operasi resolusi path; syscall ini tidak mengubah namespace filesystem yang mutable menjadi graph capability yang immutable.

Dengan directory descriptor dan kebijakan resolve yang dipilih secara sengaja, openat2() memindahkan pemeriksaan escape pathname ke path walk kernel yang sama dengan pemberian referensi file. Nilai keamanannya berasal dari titik enforcement atomik tersebut, sedangkan batasnya tetap ditentukan oleh flag yang tepat, topologi filesystem, descriptor yang dipertahankan, dan pemeriksaan otorisasi di sekitar pemanggilan.