Theo de Raadt mengusulkan penggabungan mekanisme baru ke dalam OpenBSD untuk mengurangi potensi serangan, yang diimplementasikan dengan memperluas panggilan sistem openat. Patch yang mengimplementasikan flag tambahan untuk openat dan open, yang membatasi kemampuan untuk menavigasi ke direktori atas melalui "/." dan mengakses jalur absolut, telah disiapkan untuk kernel, libc, dan beberapa aplikasi dalam sistem dasar. Perubahan tersebut belum dimasukkan ke dalam OpenBSD-current dan saat ini sedang dalam pembahasan di antara para pengembang.
Keluarga panggilan sistem openat(2) berperilaku seperti open(2), kecuali jika parameter "path" bersifat relatif, file yang akan dibuka relatif terhadap direktori yang terkait dengan deskriptor file "fd" dan bukan direktori kerja saat ini. Jika Anda memberikan jalur absolut ke openat, misalnya: int dirfd = open("/tmp", O_RDONLY | O_DIRECTORY); int hfd = openat(dirfd, "/etc/hosts", O_RDONLY);
Fungsi openat() akan mengabaikan "dirfd" dan akibatnya jalur absolut akan diproses secara normal.
Oleh karena itu, mengganti open() dengan openat() dengan sendirinya tidak meningkatkan keamanan program. Panggilan ini dapat mempercepat penguraian jalur, tetapi tidak membatasi akses ke sistem file. Flag yang melarang jalur absolut (misalnya, RESOLVE_BENEATH dan/atau RESOLVE_IN_ROOT untuk openat2 di Linux): programmer harus menambahkannya ke semua panggilan yang sesuai, dan ketika menguasai proses, penyerang dapat menggunakan cara lain untuk membuka file.
Saat mengerjakan utilitas openrsync, Theo perlu membatasi kemampuan penelusuran sistem file-nya, tetapi hal ini tidak mungkin dilakukan menggunakan fungsi unveil() dan pledge(). Kemudian ia merancang sebuah mekanisme yang mirip dengan openat(), tetapi dengan fitur keamanan yang akan melengkapi pledge/unveil atau bahkan berfungsi tanpa kehadiran keduanya.
Ide dasarnya adalah menjadikan pembatasan sebagai bagian dari deskriptor direktori itu sendiri. Untuk mencapai hal ini, kami mengusulkan flag F_BELOW, yang dapat diatur melalui fcntl(), atau flag O_BELOW untuk open(). Deskriptor "dirfd" yang dibatasi dengan cara ini hanya akan mengizinkan penelusuran ke bawah dalam pohon direktori: panggilan openat() dengan jalur absolut atau penelusuran ke atas melalui ".." akan gagal dengan kesalahan ENOENT. Jika terjadi serangan eksekusi kode, tabel deskriptor file proses akan berisi lebih sedikit "dirfd" fungsional, sehingga membatasi permukaan serangan.
Sumber: opennet.ru
