Ketika saya mencoba untuk menimpa file biner yang saat ini diluncurkan, cp
gagal menimpa, tetapi mungkin rm
saja saat itu cp
. Sebagai contoh:
user@poste:~$ cp binaryFile /tmp
user@poste:~$ sudo cp /tmp/binaryFile binaryFile
[sudo] password for user:
cp: cannot create regular file `binaryFile`: Text file busy
user@poste:~$ sudo rm binaryFile
user@poste:~$ sudo cp /tmp/binaryFile binaryFile
user@poste:~$ file binaryFile
binaryFile : ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x7ce005d9eb50e2574246b6a881e625802f7e49f2, not stripped
Ada yang tahu kenapa?
Jawaban:
Dalam kasus pertama, Anda mencoba menimpa konten file yang saat ini berjalan sebagai program. Linux tidak mengizinkan itu - jika itu terjadi, Anda akan menimpa kode tepat ketika OS mengeksekusinya; perbedaan pertama akan merusak program atau membuatnya tidak berfungsi.
Tetapi dalam kasus kedua, Anda tidak benar-benar mengubah konten file lama - Anda membuat file baru di tempatnya, sedangkan yang lama hanya kehilangan nama file tetapi menjaga kontennya tidak tersentuh.
(Ingat bahwa secara teknis
rm
tidak menghapus file, itu hanya menghapus tautan direktori - mirip dengan bagaimana menambahkan lebih banyak tautan ke file yang sama. Hanya ketika file tidak memiliki tautan dan tidak ada referensi file yang terbuka, secara otomatis akan dihapus.)ln
Sistem mereferensikan file yang digunakan dalam inode mereka, jadi tidak masalah bahwa mereka memiliki nama file yang sama - itu masih file lama yang tetap dibuka oleh sistem, dan meskipun tidak memiliki tautan lagi, itu hanya akan dihapus setelah semua program menutupnya.
sumber
/proc/*/fd
untuk mengaksesnya, dan secara opsional linkat () untuk menambahkan tautan baru ke sistem file.linkat()
, untuk alasan keamanan . (Pengecualian untuk aturan ini: kecuali jika dibuat denganopen(O_TMPFILE)
demikian ia memulai dengan nol tautan.) Jika Anda mencoba,linkat()
mengembalikan ENOENT, bahkan sebagai root. Lihat jawaban saya pada pertanyaan itu untuk skrip perl untuk benar-benar berjalanlinkat
dan membuktikan bahwa itu tidak bekerja, bahkan sebagai root: /