Bisakah file diambil oleh inode-nya?


27

Saya menjalankan perintah berikut dalam urutan yang ditentukan:

$ln a b
$ls -i a b
523669 a 523669 b
$rm -f a
$ls -i b
523669 b

Saya menyimpulkan dari tes ini bahwa perintah rmsebenarnya hanya menghapus nama file ( adalam tes ini) daripada file, karena inode masih ada dan dapat diambil melalui nama file lain ( b).

Pertanyaan saya adalah, jika sebuah file sulit dihubungkan dengan hanya satu nama file, ketika rmdieksekusi ke file tersebut, apakah file asli (yaitu, inode) dihapus sepenuhnya? Dan jika tidak, dapatkah inode file diambil tanpa nama file dan hanya melalui inode?


Kedengarannya OS khusus untuk saya.
Ignacio Vazquez-Abrams

@Ignacio Vazquez-Abrams. Maksudmu itu tergantung versi?
user43312

Tidak, maksud saya tergantung pada sistem operasi. Masing-masing memiliki cara yang berbeda (jika ada ) untuk memanfaatkan VFS.
Ignacio Vazquez-Abrams

@Ignacio Vazquez-Abrams Apakah Anda punya ide tentang RHL atau RHEL?
user43312

1
@BruceEdiger Os X semacam melakukan itu. Anda dapat mengakses objek sistem file menggunakan "URL referensi file" yang, pada dasarnya, dibangun dari nomor sistem file dan nomor node. Namun itu tidak didukung secara resmi untuk membangunnya sendiri. Alih-alih, Anda mendapatkan "URL referensi file" untuk file dan kemudian menggunakannya sebagai ganti pathname untuk akses berikutnya dalam sesi runtime yang sama sehingga aplikasi Anda menjadi tidak menyadari file yang dipindahkan di tempat lain pada volume yang sama.
File Analog

Jawaban:


29

Jika Anda mencoba membuka file melalui inode-nya, ini mem-bypass semua direktori traversal. Traversal direktori diperlukan untuk menentukan izin file dan direktori yang mengarah padanya. Tanpa traversal direktori, kernel tidak memiliki cara untuk menentukan apakah proses panggilan diizinkan untuk mengakses file.

Ada tambalan yang diusulkan ke kernel Linux untuk memungkinkan membuat tautan ke file dari deskriptor file . Itu ditolak karena menerapkan ini dengan aman akan sangat sulit .

Di Linux (dan mungkin pada varian unix lainnya untuk alasan yang sama), Anda tidak dapat membuat tautan ke file yang dihapus, jadi jika file tidak lagi memiliki nama, Anda tidak dapat menambahkannya lagi. ¹ Anda dapat membuka yang dihapus file dengan membuka tautan ajaib di bawah /proc/$pid/fd/.

Jika suatu file tidak lagi memiliki tautan apa pun dan tidak lagi terbuka, maka tidak ada lagi dan ruang yang sebelumnya digunakan oleh datanya dapat diambil kembali kapan saja.

¹ Anda mungkin dapat melakukan ini dengan memutar-mutar byte secara langsung di sistem file dengan cara yang bergantung pada sistem file, misalnya dengan debugfsuntuk ext2 / ext3 / ext4. Ini membutuhkan akses ke perangkat tempat sistem file dipasang (yaitu biasanya hanya root yang dapat mencobanya). Namun, sementara debugfs dapat mengakses file dengan inode, ini tidak membantu jika file dihapus: file akan benar-benar dihapus jika aplikasi menutupnya, dan menjalankan debugfs dalam mode baca-tulis pada sistem file yang dipasang adalah resep untuk bencana.


11

Di Linux,, debugfsdebugger sistem file ext2 / ext3 / ext4 interaktif menyediakan lnperintah yang dapat mengambil nomor inode sebagai filespecdan membuat tautan keras baru ke file yang sesuai. Namun dalam praktiknya, ini mengharuskan file yang tidak ditautkan tetap terbuka oleh suatu proses , mempertahankan deskriptor file terbuka /proc/[pid]/fd/[n]. Mencoba ini pada file yang dihapus kemungkinan besar akan menyebabkan korupsi sistem file.

Hal ini karena untuk memastikan bahwa ext3 (dan dalam ekstensi ext4) dapat dengan aman melanjutkan pembatalan tautan setelah kerusakan, ia sebenarnya nol keluar dari blokir pointer di inode , sedangkan ext2 hanya menandai blok-blok ini sebagai tidak digunakan dalam blok bitmap dan menandai inode sebagai "dihapus" dan meninggalkan pointer blok saja. Meski begitu, karena sistem file perlu di-mount baca-tulis untuk membuat tautan keras, blok yang disediakan untuk file yang dihapus mungkin sudah dialokasikan kembali.

Sebelum kernel versi 2.6.39 dulu opsi yang diperkenalkan di GNU coreutils v8.0 dapat digunakan untuk memulihkan file yang tidak terhubung melalui deskriptor file terbuka jika file yang tidak terhubung dan hardlink baru berada pada sistem file tmpfs . Kemampuan ini sejak itu dinonaktifkan , karena, seperti yang ditunjukkan Gilles , pertimbangan keamanan yang terlibat dalam memungkinkan pembuatan tautan langsung dari deskriptor file.ln -L|--logical/proc/[pid]/fd/[n]


Saya baru saja mencoba menggunakan ln -Luntuk memulihkan file yang dihapus dari / proc dan mendapat kesalahan: "Tidak ada file atau direktori", jadi saya tidak berpikir itu benar-benar mendukung ini. Saya memiliki coreutils 8.21.
wingedsubmariner

1
ln -Ltidak melakukan apa yang Anda katakan. Ia memberi tahu lnbahwa jika sumbernya adalah tautan simbolis, ia harus menghubungkan tautan dengan target. Tautan simbolis /proc/$pid/fdkhusus, dan tautan keras (deleted)tautan tidak berfungsi.
Gilles 'SO- stop being evil'

Juga debugfstidak akan membantu jika file tersebut telah dihapus - kecuali jika Anda ingin mengambil risiko menjalankannya dalam mode baca-tulis pada sistem file yang terpasang, yang kemungkinan akan benar-benar memotong seluruh sistem file.
Gilles 'SO- stop being evil'

Diperbarui jawabannya sehubungan dengan ln -L. Dulu dimungkinkan untuk membuat tautan keras dari /proc/[pid]/fd/[n]menggunakannya dalam keadaan khusus tertentu, tetapi sejak itu telah diperbaiki.
Thomas Nyman

1
debugfsTingkatnya lnsangat rendah dan hanya membuat nama, tidak memperbarui hitungan atau menghapus tanda blok sebagai tidak digunakan sehingga sangat berbahaya . Lebih memilih debugfs's undelyang des semua itu. Peringatan: debugfsini tidak dijalankan pada mount filesystem kecuali jika Anda ingin mengambil kesempatan pada pembakaran FS Anda menjadi abu.
Lloeki

9

Perintah 'ln' dan 'rm' telah bekerja persis seperti ini di setiap sistem file UNIX sejak awal 1970-an. Mac OSX, BSD dan Linux semuanya mewarisi desain asli ini.

Dengan sendirinya, file UNIX tidak memiliki nama, hanya nomor inode atau inum. Tetapi Anda hanya dapat mengaksesnya melalui entri dalam file "direktori" khusus yang mengaitkan nama dengan inum yang dimaksud; Anda tidak dapat menentukan inum secara langsung.

Direktori adalah dirinya sendiri file, sehingga Anda juga harus mengakses itu melalui (lain) direktori dan sebagainya, melalui serangkaian nama direktori dipisahkan oleh garis miring (/) dikenal sebagai "nama jalan". Jalur dimulai di "direktori kerja saat ini" dari proses kecuali nama dimulai dengan "/", dalam hal ini dimulai dengan direktori root sistem file. Misalnya, jika nama jalur tidak mengandung karakter "/", maka itu diharapkan menjadi entri dalam direktori saat ini.

File non-direktori dapat memiliki sejumlah nama jalur, yang dikenal sebagai "tautan keras", dan akan terus ada sampai semua nama jalurnya dihapus dan proses terakhir telah menutup file. Kemudian file tersebut sebenarnya dihapus dan ruangnya ditandai sebagai tersedia untuk digunakan kembali. Artinya, Anda dapat membuat () atau membuka () file yang terhubung sendiri dan kemudian memutuskan tautan () sehingga tidak lagi muncul di ruang nama sistem file, tetapi file tersebut akan terus ada sampai Anda menutupnya. Ini berguna untuk file awal sementara yang tidak akan dibaca oleh program lain.

Meskipun direktori memiliki nomor inode, sebagian besar sistem file tidak mengizinkan tautan keras ke dalamnya; mereka hanya dapat muncul di satu direktori lain. (Satu pengecualian yang tidak biasa adalah sistem file Mac OSX HFS +; ini memungkinkan backup Time Machine berfungsi.) Anda masih dapat membuat "tautan lunak" ke direktori (atau file lainnya). Tautan lunak menyerupai entri direktori kecuali bahwa itu berisi nama path lain daripada inum.

Setiap file UNIX memiliki izin pemilik, grup, dan akses. Itu perlu tetapi tidak cukup bahwa mereka membiarkan Anda membuka file; Anda juga harus memiliki setidaknya menjalankan izin untuk setiap direktori di pathname yang Anda gunakan untuk merujuknya. Itu sebabnya tidak ada cara standar untuk membuka file UNIX dengan nomor inode-nya; yang akan mem-bypass mekanisme keamanan yang penting dan banyak digunakan.

Tetapi ini tidak menjelaskan mengapa tidak ada cara standar bagi pengguna root (yang diistimewakan) untuk membuka file dengan nomor inode, karena bagaimanapun pengecekan izin dilewati. Ini akan sangat berguna untuk fungsi manajemen sistem tertentu seperti cadangan. Sepengetahuan saya, mekanisme semacam itu memang ada, tetapi semuanya khusus sistem file; tidak ada cara umum untuk melakukannya untuk sistem file UNIX.


1
Maju dalam /diam, sehingga diucapkan "slash".
ctrl-alt-delor

4

Pertanyaannya dapat diambil secara teoritis (yang dapat dicapai dengan debugfs) atau secara pragmatis (situasi darurat). Dalam kasus terakhir, saya menganggap maksudnya adalah menyelamatkan hari dan mengembalikan konten file, mungkin sangat mendesak (itulah cara saya mendarat di pertanyaan ini, jadi saya pikir itu masih relevan dan berguna).

Karena tidak ada API kernel, debugfstidak boleh dijalankan pada sistem file langsung karena memanipulasi struktur FS secara langsung. Oleh karena itu untuk melakukannya secara langsung, Anda harus mendapatkan nama file lain. Dengan asumsi file masih terbuka oleh beberapa proses (proses apa pun), orang dapat menjangkau deskriptor file yang selalu nyaman di /proc:

$ lsof -F pf "$PWD/a" | sed 's/^p//' # find pid and file descriptor number of any process having the file open
$ pid=1234
$ ls -l /proc/$pid/fd/* | grep "$PWD/a" # find file descriptor number
$ fd=42
$ cat /proc/$pid/fd/$fd > "$PWD/a.restored" # read contents to a new filename

Kiat:

  • jika Anda ragu dengan fd yang tepat, Anda dapat menjalankan perintah seperti fileitu
  • jika ada proses menulis ke file, pastikan untuk menghentikan proses itu ASAP atau Anda tidak akan mendapatkan data terbaru. Trik (yang belum diuji) mungkin dengan membuka file yang hanya dapat dibaca melalui fd dengan beberapa proses lain (coba tail -f < /proc/$pid/fd/$fd > /dev/null, keluar dari proses penulisan sehingga keluar dengan bersih, dan gunakan fd proses baru.

2
Itu harus tail -f < /proc/...di ujung kedua.
Murray Jensen

Atau gunakan tail -c +0 -f untuk menyalinnya di tempat pertama alih-alih cat, jika proses penulisan hanya menambahkan (tidak mencari kembali dan menulis ulang). Keluar dari proses lain sebelumnya tail, lalu tunggu tailhingga akhir file.
Peter Cordes
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.