Sebuah service dapat perlu mengeksekusi program helper setelah menerima input yang tidak tepercaya. Jika salah satu program tersebut memiliki set-user-ID, set-group-ID, atau file capabilities, execve() biasa dapat melintasi batas privilege meskipun proses pemanggil tidak bermaksud memperoleh otoritas tambahan. Linux no_new_privs mengubah transisi tersebut: setelah atribut ini ditetapkan pada sebuah thread, pemanggilan execve() berikutnya tidak dapat memberikan privilege yang tidak dimiliki pemanggil pada saat eksekusi.

Properti ini sengaja memiliki cakupan sempit. Ia membatasi penambahan privilege melalui eksekusi program; ia tidak menghapus otoritas yang sudah dimiliki proses. Perbedaan tersebut membuat no_new_privs berguna sebagai batas eksekusi satu arah, tetapi tidak cukup sebagai sandbox lengkap.

Bit ini merupakan atribut proses satu arah

Sebuah thread menetapkan atribut dengan prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0). Setelah pemanggilan berhasil, nilainya tidak dapat dihapus. Proses anak yang dibuat melalui fork() dan clone() mewarisinya, sedangkan execve() mempertahankannya.

Sifat satu arah ini penting karena sebuah proses dapat menetapkan batas sebelum menyerahkan kontrol kepada kode yang kurang tepercaya. Kode tersebut tidak dapat menghapus bit lalu mengeksekusi binary berprivilege untuk membuka kembali jalur elevasi saat eksekusi.

Pada antarmuka kernel, pengaturan ini berlaku per thread. Dalam program multithread, implementasi perlu memperhitungkan thread mana yang telah menetapkan atribut serta jalur eksekusi mana yang dapat membuat proses turunan. Menganggapnya sebagai switch yang otomatis berlaku untuk seluruh proses dapat meninggalkan thread lain di luar batas yang dimaksud.

execve menekan tiga mekanisme elevasi umum

Saat no_new_privs aktif, execve() tidak menghormati bit mode set-user-ID dan set-group-ID sebagai mekanisme untuk menambah privilege. File capabilities juga dicegah agar tidak menambahkan privilege selama transisi eksekusi.

Perilaku ini tidak sama dengan menganggap properti filesystem tersebut tidak ada. Kernel tetap menjalankan transisi eksekusi berdasarkan aturan kredensial normalnya, tetapi transisi dibatasi agar program baru tidak menjadi lebih berprivilege melalui mekanisme tersebut.

Hal ini juga memengaruhi pemrosesan Linux Security Module. Kontrak kernel mencegah execve() memakai transisi LSM untuk melonggarkan pembatasan yang berlaku pada pemanggil. Setiap security module tetap memiliki semantiknya sendiri, sehingga kebijakan deployment masih menentukan label dan pemeriksaan yang berlaku secara spesifik.

Konsekuensi praktisnya, helper yang dirancang menjadi berprivilege hanya karena executable memiliki bit set-user-ID dapat tetap dieksekusi tanpa memperoleh elevasi tersebut. Software yang mengasumsikan helper selalu mendapatkan identitas berprivilege dapat gagal setelah batas ini diaktifkan.

Otoritas yang sudah ada tetap bertahan

Namanya dapat memberi kesan pengurangan privilege yang lebih luas daripada kontrak kernel sebenarnya. no_new_privs tidak mencabut file descriptor terbuka, mapped memory, kredensial, namespace, akses jaringan, atau resource lain yang sudah tersedia bagi proses. Mekanisme ini juga tidak dengan sendirinya menghapus capability yang sudah ada pada set kredensial terkait.

Proses yang sejak awal memiliki otoritas berbahaya dapat tetap memilikinya setelah bit ditetapkan. Mekanisme ini hanya memblokir privilege tambahan yang berasal dari jalur execve() yang tercakup dalam kontraknya.

Hal tersebut memisahkan dua operasi keamanan yang sering digabungkan saat menyiapkan sandbox. Penurunan privilege mengurangi otoritas yang sudah dimiliki. no_new_privs mencegah transisi eksekusi tertentu menambahkan otoritas di kemudian waktu. Desain confinement yang kuat dapat memerlukan keduanya, ditambah kontrol terhadap filesystem, jaringan, system call, dan descriptor yang diwariskan.

Seccomp memakai batas ini untuk pemasangan filter tanpa privilege

Pemasangan filter seccomp di Linux memiliki hubungan langsung dengan no_new_privs. Thread tanpa CAP_SYS_ADMIN di user namespace-nya harus mengaktifkan no_new_privs sebelum memasang filter seccomp melalui SECCOMP_SET_MODE_FILTER; jika tidak, operasi gagal.

Persyaratan tersebut mencegah proses tanpa privilege memasang filter lalu mengeksekusi program set-user-ID yang akan mewarisi filter di bawah identitas baru yang lebih berprivilege. Tanpa penghalang privilege saat eksekusi, syscall filtering dapat menjadi sarana untuk mengubah perilaku program berprivilege dengan kondisi yang dikendalikan penyerang.

Hubungan ini tidak membuat kedua mekanisme dapat saling menggantikan. Seccomp membatasi antarmuka system call sesuai semantik filternya. no_new_privs membatasi perolehan privilege melalui eksekusi. Mengaktifkan salah satunya tidak menghasilkan permukaan enforcement milik mekanisme lainnya.

Batas ini tidak membuat eksekusi menjadi aman secara otomatis

Executable tetap dapat berbahaya atau tidak aman tanpa memperoleh UID, GID, atau capability baru. Program tersebut dapat bertindak memakai izin pemanggil yang sudah ada, memanfaatkan file descriptor yang diwariskan, mengubah file yang writable, berkomunikasi melalui socket yang tersedia, atau memakai otoritas yang diberikan lingkungan proses.

Pengaturan ini juga tidak memvalidasi asal atau integritas executable. Resolusi path, permission filesystem, konfigurasi mount, signature, dan mekanisme integritas konten tetap menjadi persoalan terpisah.

Bagi service launcher dan sandbox runtime, properti yang bernilai adalah sifat komposisinya: setelah bit ditetapkan pada jalur eksekusi terkait, eksekusi program berikutnya tidak dapat memakai mekanisme exec-time yang tercakup untuk naik melampaui kondisi privilege pemanggil. Kontrol lain kemudian dapat mempersempit otoritas yang masih tersisa.

Penempatan menentukan batas kepercayaan efektif

Pola operasional yang paling kuat adalah menetapkan no_new_privs setelah seluruh setup yang memang memerlukan privilege selesai dan sebelum kontrol mencapai kode yang tidak boleh mendapatkan kembali privilege melalui eksekusi. Penetapan terlalu awal dapat merusak helper sah yang masih memerlukan transisi kredensial saat eksekusi. Penetapan terlalu lambat membiarkan jalur eksekusi sebelumnya tetap mampu melintasi batas tersebut.

Karena atribut ini tidak dapat dibalik, penempatannya merupakan keputusan arsitektur, bukan toggle sementara. Pohon proses di bawah titik tersebut mewarisi pembatasan yang bertahan, sehingga lokasi pemanggilan menjadi bagian dari desain batas kepercayaan aplikasi.

no_new_privs paling tepat diperlakukan sebagai batas atas privilege saat eksekusi. Mekanisme ini tidak mendefinisikan seluruh sandbox, tetapi menutup kelas transisi privilege tertentu dalam bentuk yang tidak dapat dinonaktifkan oleh proses turunannya.