Perché un utente normale non può eliminare un sottovolume btrfs


12

Utilizzando un filesystem btrfs creato dall'utente montato in loop, con le autorizzazioni impostate correttamente, un utente è in grado di creare liberamente sottovolumi btrfs:

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

Tuttavia, il tentativo di eliminare il sottovolume appena creato genera un errore:

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'

L'utente root, ovviamente, è in grado di eliminarlo:

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

Questa differenza di comportamento tra le operazioni di creazione ed eliminazione sembra un po 'strana. Qualcuno può far luce su questo?

Ecco l'esatta sequenza di comandi:

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

Ecco le autorizzazioni:

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

E la riga pertinente su df -T:

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

La distro è un Debian Wheezy, 3.2.0-4-686-paekernel, v0.19btrfs-tools. La situazione si verifica ancora su Ubuntu Saucy, 3.11.0-4-generickernel, v0.20-rc1btrfs-tools.


Dalla mia comprensione questo tipo di filesystem è ancora sperimentale e non pronto per la produzione.
mdpc,

Puoi aggiungere l'output di df -Te btrfs version? Quando ho provato lo stesso ho ricevuto il seguente errore "ERRORE: impossibile creare sottovolume - Autorizzazione negata"
bsd

@mdpc Anche se è vero, btrfs è in circolazione da alcuni anni, e si prevede che sarà alquanto stabile in questa fase. A questo punto può essere ancora utile capire se si tratta di un bug o di una "caratteristica".
goncalopp,

@bdowning Ho aggiunto la sequenza esatta di comandi, df e le versioni che ho usato.
goncalopp,

Il kernel 3.2 ora ha più di un anno e mezzo. Se vuoi giocare con filesystem sperimentali, potresti voler eseguire un kernel più aggiornato.
psusi,

Risposte:


14

Bene, questa è stata un'esperienza di apprendimento per me, ma alla fine l'ho capito. Spiegherò qui il mio processo in modo che sia più facile sapere come capire queste cose da soli (la documentazione di BTRFS, come sono sicuro che hai scoperto, è relativamente incompleta per il momento).

All'inizio ho pensato che la creazione del sottovolume fosse un ioctlcon un gestore che non faceva alcun controllo di capacità (che poteva o meno essere stato un problema di sicurezza a seconda che ci fosse qualche logica ad esso) mentre eliminarlo stava modificando direttamente i metadati (e quindi l'utente potrebbe richiedere CAP_SYS_RAWIOdi funzionare correttamente).

Per verificare, ho aperto il btrfs-utilscodice sorgente e questo è quello che ho trovato:

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);

Bene, questo non è utile, sono entrambi ioctl (interessante nota a margine: "istantanea" è spesso usata in modo intercambiabile nel codice sorgente con "sottovolume" per qualche motivo). Quindi sono andato al codice sorgente del kernel e ho trovato entrambi i gestori fs/btrfs/ioctl.c.

Alla fine, l'ho rintracciato alla btrfs_ioctl_snap_destroy()e sulla linea 2116:

     if (!capable(CAP_SYS_ADMIN)){

In particolare, questo è un controllo se non hanno la capacità ma se ce l'hanno, la logica salta direttamente all'esecuzione dell'operazione. Il corpo dell'istruzione if verifica se è l'utente normale il proprietario dell'inode del sottovolume e l' USER_SUBVOL_RM_ALLOWEDopzione BTRFS è abilitata che continua l'esecuzione del gestore. Se non hanno nemmeno il gestore ioctl esce con un errore.

Quindi sembra che distruggere una "istantanea" (alias "sottovolume") richieda generalmente un utente che ha CAP_SYS_ADMIN(o USER_SUBVOL_RM_ALLOWEDdeve essere abilitato e l'utente "possiede" il sottovolume dato). Fantastico, per quanto riguarda la creazione di un'istantanea / volume?

Il gestore per lo ioctl sembra essere btrfs_ioctl_snap_create()questo gestore sembra non contenere alcuna chiamata capable()diretta o indiretta. Dal momento che questo è il modo principale di mediare l'accesso, lo prendo per significare che la creazione di sottovolume ha sempre successo. Questo spiega a livello funzionale perché stai vedendo quello che stai vedendo.

Non posso parlare del motivo per cui questo è considerato desiderabile al di fuori del caso d'uso principale di BTRFS con un server con accesso utente limitato. Non è sufficiente ma non vedo alcun codice per interrompere effettivamente l'operazione. Se non riesci a trovare una risposta al perché (e ti interessa averlo) potresti doverlo chiedere alla mailing list del kernel.

Conclusione

La mia ricerca sembra indicare che chiunque può creare sottovolumi ma per eliminare un sottovolume è necessario disporre CAP_SYS_ADMINo è necessario che l'utente chiamante sia il proprietario dell'inode del sottovolume e sia USER_SUBVOL_RM_ALLOWEDabilitato.

La creazione del sottovolume non ha senso, quindi probabilmente mi manca un modo indiretto di negare l'operazione poiché sembra un modo semplice per fare un sistema.

Nota: non sono in un posto dove posso verificare questa funzionalità ma una volta tornato a casa posso impostare se la setcapmagia funziona come previsto .


Il modo in cui ha senso (riguardo al tuo DoS) è se rmdirè consentito su sottovolumi vuoti. Quindi rm -rfunzionerà in modo trasparente. Sfortunatamente il codice semplicemente non è stato sviluppato (ancora). Sembra che qualcuno abbia fatto tre tentativi nel 2010 e poi abbia rinunciato :(. Spinics.net/lists/linux-btrfs/msg06499.html
sourcejedi

5

L'eliminazione di un volume secondario consente a qualcuno di scollegare i file che non possiedono. A mio avviso, i file che un utente privilegiato scrive in una posizione scelta da un utente meno privilegiato sono un gioco leale, ma la persona che ha contribuito alla funzionalità di eliminazione non root probabilmente non si sentiva abbastanza sicura della sicurezza e della contentezza di quella semantica per inviarli come nuova opzione di montaggio ( mount -o user_subvol_rm_allowed).


1
Bene, sorprendentemente in UNIX® puoi facilmente scollegare un file che non possiedi - devi solo avere un permesso di scrittura nella sua directory.
poige,

Ho lo stesso problema su fedora 20, ho / home in un sottovolume, sto usando l'utente root, ma comunque, non posso cancellare / home
c4f4t0r

poige, se il file in questione si trova in una cartella di cui non sei il proprietario, non puoi scollegarlo e non puoi scollegare la cartella stessa poiché contiene ancora materiale. È possibile eseguire solo operazioni non distruttive su questa cartella, come spostarla o rinominarla.
slitta,

-1

"Impossibile eliminare / home" (che è @home).

Perché dovresti voler eliminare il sottovolume sul quale risiede il tuo / home / account, a meno che tu non abbia creato un'istantanea / home_snapshot_yymmdd per sostituire / home con?

Sono nuovo nell'uso di btrfs ma questo è quello che ho scoperto: @ / e @home (/ e / home) vengono creati da btrfs quando viene installato sul tuo HD come file system. A meno che tu non stia eseguendo un ripristino di / home da un'istantanea precedente, a quanto ho capito, ti taglieresti alle ginocchia.

Tuttavia, puoi montare il dispositivo su cui / home si trova, COME ROOT, usando mount / dev / sa / mnt / (o qualunque dispositivo su cui sia in esecuzione il tuo sistema btrfs in esecuzione) Quindi cd su / mnt / e da lì emetti il ​​comando delete per @casa. Quindi puoi usare il comando mv per spostare @home_snapshot_yymmdd (o come mai lo hai chiamato) su @home. Lo spostamento può richiedere ore, a seconda delle dimensioni di @home. Quindi riavvia il CD sul tuo account ed emetti sudo umount / mnt / Non ti sei mai disconnesso o spento il tuo sistema. Questa è una bellezza di btrfs.


Sembra che lo abbiano già fatto. Btrfs non crea @ e @home se non glielo dici (o la tua distribuzione come Ubuntu lo fa per te).
Anthon,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.