Jawabannya adalah Anda tidak bisa, kecuali sistem file Anda memiliki bug. Inilah alasannya:
Ada sistem panggilan untuk mengubah nama file Anda didefinisikan dalam fs/namei.c
disebut renameat
:
SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
int, newdfd, const char __user *, newname)
Saat panggilan sistem dipanggil, ia melakukan pencarian jalur ( do_path_lookup
) pada namanya. Terus telusuri ini, dan kita sampai pada link_path_walk
yang memiliki ini:
static int link_path_walk(const char *name, struct nameidata *nd)
{
struct path next;
int err;
unsigned int lookup_flags = nd->flags;
while (*name=='/')
name++;
if (!*name)
return 0;
...
Kode ini berlaku untuk sistem file apa pun. Apa maksudnya ini? Ini berarti bahwa jika Anda mencoba melewatkan parameter dengan '/'
karakter aktual sebagai nama file menggunakan cara tradisional, itu tidak akan melakukan apa yang Anda inginkan. Tidak ada cara untuk melarikan diri dari karakter tersebut. Jika filesystem "mendukung" ini, itu karena mereka:
- Gunakan karakter unicode atau sesuatu yang terlihat seperti garis miring tetapi bukan.
- Mereka punya bug.
Selain itu, jika Anda melakukan masuk dan mengedit byte untuk menambahkan karakter garis miring menjadi nama file, hal-hal buruk akan terjadi. Itu karena Anda tidak pernah bisa merujuk ke file ini dengan nama :( karena kapan pun Anda melakukannya, Linux akan menganggap Anda merujuk ke direktori yang tidak ada. Menggunakan teknik 'rm *' juga tidak akan berhasil, karena bash hanya memperluasnya ke nama file. Bahkan rm -rf
tidak akan berhasil, karena strace sederhana mengungkapkan bagaimana segala sesuatunya berjalan di bawah tenda (disingkat):
$ ls testdir
myfile2 out
$ strace -vf rm -rf testdir
...
unlinkat(3, "myfile2", 0) = 0
unlinkat(3, "out", 0) = 0
fcntl(3, F_GETFD) = 0x1 (flags FD_CLOEXEC)
close(3) = 0
unlinkat(AT_FDCWD, "testdir", AT_REMOVEDIR) = 0
...
Perhatikan bahwa panggilan ke ini unlinkat
akan gagal karena mereka perlu merujuk ke file menurut namanya.