Mengapa pengguna biasa tidak dapat menghapus subvolume btrfs

12

Menggunakan loop-mount pengguna membuat sistem file btrfs, dengan izin yang ditetapkan dengan benar, pengguna dapat dengan bebas membuat subvolume btrfs:

user@machine:~/btrfs/fs/snapshots$ /sbin/btrfs sub create newsubvol
Create subvolume './newsubvol'

Namun, mencoba untuk menghapus hasil subvolume yang baru dibuat dalam kesalahan:

user@machine:~/btrfs/fs/snapshots$ /sbin/btrfs sub del newsubvol
Delete subvolume '/home/user/btrfs/fs/snapshots/newsubvol'
ERROR: cannot delete '/home/user/btrfs/fs/snapshots/newsubvol'

Pengguna root, tentu saja, dapat menghapusnya:

root@machine:/home/user/btrfs/fs/snapshots# /sbin/btrfs sub del newsubvol
Delete subvolume '/home/user/btrfs/fs/snapshots/newsubvol'

Perbedaan perilaku antara operasi membuat dan menghapus ini agak aneh. Adakah yang bisa menjelaskan ini?

Inilah urutan perintah yang tepat:

user@machine:~$ dd if=/dev/zero of=btrfs_disk bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 1.2345 s, 84.9 MB/s
user@machine:~$ mkdir mountpoint
user@machine:~$ /sbin/mkfs.btrfs btrfs_disk

WARNING! - Btrfs Btrfs v0.19 IS EXPERIMENTAL
WARNING! - see http://btrfs.wiki.kernel.org before using

SMALL VOLUME: forcing mixed metadata/data groups
Created a data/metadata chunk of size 8388608
fs created label (null) on btrfs_disk
    nodesize 4096 leafsize 4096 sectorsize 4096 size 100.00MB
Btrfs Btrfs v0.19
user@machine:~$ sudo mount btrfs_disk mountpoint/
user@machine:~$ cd mountpoint/
user@machine:~/mountpoint$ /sbin/btrfs sub create test
Create subvolume './test'
user@machine:~/mountpoint$ /sbin/btrfs sub delete test
Delete subvolume '/home/user/mountpoint/test'
ERROR: cannot delete '/home/user/mountpoint/test' - Operation not permitted

Berikut ini izinnya:

user@machine:~/mountpoint$ ls -la
total 4
drwxr-xr-x 1 user user    8 Set  4 09:30 .
drwx------ 1 user user 4486 Set  4 09:29 ..
drwx------ 1 user user    0 Set  4 09:38 test

Dan baris yang relevan pada df -T:

Filesystem              Type     1K-blocks      Used Available Use% Mounted on
/dev/loop0              btrfs       102400        32     98284   1% /home/user/mountpoint

Distronya adalah Debian Wheezy, 3.2.0-4-686-paekernel, v0.19btrfs-tools. Situasi masih terjadi pada Ubuntu Saucy, 3.11.0-4-generickernel, v0.20-rc1btrfs-tools.

goncalopp
sumber
Dari pemahaman saya, tipe sistem file ini masih eksperimental dan belum siap produksi.
mdpc
Bisakah Anda menambahkan output dari df -Tdan btrfs version? Ketika saya mencoba yang sama saya mendapat kesalahan berikut "ERROR: tidak dapat membuat subvolume - Izin ditolak"
bsd
@ mdpc Meskipun itu benar, btrfs telah ada selama beberapa tahun, dan itu diharapkan agak stabil pada tahap ini. Mungkin masih berguna untuk memahami apakah ini bug atau 'fitur', pada titik ini.
goncalopp
@membalas Saya telah menambahkan urutan tepat dari perintah, df, dan versi yang saya gunakan.
goncalopp
Kernel 3.2 sekarang lebih dari satu setengah tahun. Jika Anda ingin bermain dengan sistem file eksperimental, Anda mungkin ingin menjalankan kernel yang lebih baru.
psusi

Jawaban:

14

Yah ini adalah pengalaman belajar bagi saya tetapi saya akhirnya menemukan jawabannya. Saya akan menjelaskan proses saya di sini sehingga lebih mudah untuk mengetahui cara mengetahui hal ini sendiri (dokumentasi BTRFS, seperti yang saya yakin Anda ketahui, relatif tidak lengkap untuk saat ini).

Pada awalnya saya berpikir bahwa membuat subvolume adalah ioctldengan handler yang tidak melakukan pemeriksaan kemampuan (yang mungkin atau mungkin tidak menjadi masalah keamanan tergantung pada apakah ada logika untuk itu) sedangkan menghapusnya adalah memodifikasi metadata secara langsung (dan karenanya pengguna mungkin harus CAP_SYS_RAWIObekerja dengan benar).

Untuk memverifikasi, saya membuka btrfs-utilskode sumber dan inilah yang saya temukan:

Create subvolume, cmds-receive.c Line 180:
         ret = ioctl(r->dest_dir_fd, BTRFS_IOC_SUBVOL_CREATE, &args_v1);

Delete subvolume, cmds-subvolume.c Line 259:
         res = ioctl(fd, BTRFS_IOC_SNAP_DESTROY, &args);

Yah, itu tidak membantu, mereka berdua ioctl (catatan menarik: "snapshot" sering digunakan secara bergantian dalam kode sumber dengan "subvolume" untuk beberapa alasan). Jadi saya pergi ke kode sumber kernel dan menemukan kedua penangan di fs/btrfs/ioctl.c.

Akhirnya, saya melacaknya kembali ke btrfs_ioctl_snap_destroy()dan di jalur 2116:

     if (!capable(CAP_SYS_ADMIN)){

Secara khusus, ini adalah cek jika mereka tidak memiliki kemampuan tetapi jika mereka memilikinya, logikanya langsung dilewati untuk melakukan operasi. Isi pernyataan if memeriksa apakah pengguna biasa yang merupakan pemilik inode subvolume dan USER_SUBVOL_RM_ALLOWEDopsi BTRFS memungkinkannya melanjutkan eksekusi handler. Jika mereka tidak memiliki salah satu handler ioctl keluar dengan kesalahan.

Jadi sepertinya menghancurkan "snapshot" (alias "subvolume") umumnya membutuhkan pengguna yang memilikinya CAP_SYS_ADMIN (atau untuk USER_SUBVOL_RM_ALLOWEDdiaktifkan dan pengguna "memiliki" subvolume yang diberikan). Hebat, bagaimana dengan membuat snapshot / volume?

Handler untuk ioctl tampaknya btrfs_ioctl_snap_create()handler ini tampaknya tidak berisi panggilancapable() secara langsung atau tidak langsung. Karena itulah cara utama akses ditengahi saya menganggap ini berarti bahwa penciptaan subvolume selalu berhasil. Ini menjelaskan pada tingkat fungsional mengapa Anda melihat apa yang Anda lihat.

Saya tidak bisa bicara mengapa ini dianggap diinginkan di luar kasus penggunaan utama BTRFS adalah dengan server dengan akses pengguna terbatas. Itu tidak cukup tetapi saya tidak melihat kode apa pun untuk benar-benar menghentikan operasi. Jika Anda tidak dapat menemukan jawaban mengapa itu (dan Anda ingin memilikinya), Anda mungkin harus bertanya pada milis kernel.

Kesimpulan

Penelitian saya tampaknya menunjukkan bahwa siapa pun dapat membuat subvolume tetapi untuk menghapus subvolume Anda harus memiliki CAP_SYS_ADMINatau perlu benar bahwa pengguna panggilan adalah pemilik inode subvolume dan USER_SUBVOL_RM_ALLOWEDdiaktifkan.

Penciptaan subvolume tidak masuk akal jadi saya mungkin kehilangan beberapa cara tidak langsung bahwa operasi ditolak karena sepertinya cara mudah untuk melakukan DoS sistem.

Catatan: Saya tidak berada di tempat di mana saya dapat memverifikasi fungsionalitas ini, tetapi begitu saya pulang, saya dapat mengatur apakah setcapsihir berfungsi seperti prediksi ini.

Bratchley
sumber
Cara masuk akal (mengenai kekhawatiran DoS Anda) adalah jika rmdirdiizinkan pada subvolume kosong. Kemudian rm -rakan bekerja secara transparan. Sayangnya kode tersebut belum dikembangkan (belum). Sepertinya seseorang melakukan tiga percobaan pada tahun 2010 dan kemudian menyerah :(. Spinics.net/lists/linux-btrfs/msg06499.html
sourcejedi
5

Menghapus subvolume memungkinkan seseorang untuk memutuskan tautan file yang bukan miliknya. Menurut pendapat saya, file yang ditulis oleh pengguna yang memiliki hak istimewa di lokasi yang dipilih oleh pengguna yang kurang beruntung adalah permainan yang adil, tetapi orang yang berkontribusi pada fungsi penghapusan non-root mungkin tidak merasa cukup percaya diri tentang seberapa aman semantik itu dan puas untuk mengirimkannya sebagai opsi pemasangan baru ( mount -o user_subvol_rm_allowed).

Gabriel
sumber
1
Yah, anehnya di UNIX® Anda dapat dengan mudah memutuskan tautan file yang bukan milik Anda - Anda hanya perlu memiliki izin menulis di direktori-nya.
poige
Saya memiliki masalah yang sama pada fedora 20, saya memiliki / home dalam subvolume, saya menggunakan root pengguna, tetapi bagaimanapun juga, saya tidak dapat menghapus / home
c4f4t0r
poige, jika file yang dimaksud berada di folder yang bukan milik Anda, Anda tidak dapat memutuskan tautan dan Anda tidak dapat memutuskan tautan folder itu sendiri karena masih mengandung barang-barang di dalamnya. Anda hanya dapat melakukan operasi yang tidak merusak pada folder ini, seperti memindahkannya atau menamai ulangnya.
sleblanc
-1

"Tidak dapat menghapus / beranda" (yaitu @rumah).

Mengapa Anda ingin menghapus subvolume tempat / home / akun Anda berada, kecuali Anda telah membuat snapshot / home_snapshot_yymmdd untuk diganti / home dengan?

Saya baru menggunakan btrfs tetapi inilah yang saya temukan: @ / dan @home (/ dan / home) dibuat oleh btrfs ketika diinstal pada HD Anda sebagai sistem file. Kecuali jika Anda melakukan restore / home dari snapshot sebelumnya, seperti yang saya mengerti, Anda akan memotong diri Anda sendiri.

Namun, Anda dapat memasang perangkat yang / home aktif, SEBAGAI ROOT, menggunakan mount / dev / sa / mnt / (atau perangkat apa pun yang menjalankan sistem btrf Anda aktif) Kemudian cd ke / mnt / dan dari sana mengeluarkan perintah hapus untuk @rumah. Kemudian Anda dapat menggunakan perintah mv untuk memindahkan @home_snapshot_yymmdd (atau apa pun nama Anda) ke @home. Perpindahan mungkin memakan waktu berjam-jam, tergantung pada ukuran @ rumah. Kemudian CD kembali ke akun Anda sendiri dan mengeluarkan sudo umount / mnt / Anda tidak pernah benar-benar keluar atau mematikan sistem Anda. Itu keindahan btrfs.

GreyGeek
sumber
Sepertinya mereka sudah melakukannya. Btrfs tidak membuat @ dan @rumah kecuali Anda memberi tahu mereka (atau distro Anda seperti Ubuntu melakukannya untuk Anda).
Anthon