Pourquoi un utilisateur normal ne peut-il pas supprimer un sous-volume btrfs

12

En utilisant un système de fichiers btrfs créé par l'utilisateur monté en boucle, avec les autorisations définies correctement, un utilisateur peut créer librement des sous-volumes btrfs:

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

Cependant, la tentative de suppression du sous-volume nouvellement créé entraîne une erreur:

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'utilisateur root, bien sûr, peut le supprimer:

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

Cette différence de comportement entre les opérations de création et de suppression semble un peu étrange. Quelqu'un peut-il faire la lumière là-dessus?

Voici la séquence exacte des commandes:

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

Voici les autorisations:

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

Et la ligne pertinente sur df -T:

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

La distribution est un Debian Wheezy, 3.2.0-4-686-paekernel, v0.19btrfs-tools. La situation se produit toujours sur Ubuntu Saucy, 3.11.0-4-generickernel, v0.20-rc1btrfs-tools.

goncalopp
la source
D'après ma compréhension, ce type de système de fichiers est encore expérimental et n'est pas prêt pour la production.
mdpc
Pouvez-vous ajouter la sortie de df -Tet btrfs version? Lorsque j'ai essayé la même chose, j'ai eu l'erreur suivante "ERREUR: impossible de créer un sous-volume - Autorisation refusée"
bsd
@mdpc Bien que cela soit vrai, btrfs existe depuis quelques années et devrait être quelque peu stable à ce stade. Il peut encore être utile de comprendre s'il s'agit d'un bogue ou d'une «fonctionnalité» à ce stade.
goncalopp
@bdowning J'ai ajouté la séquence exacte des commandes, df et les versions que j'ai utilisées.
goncalopp
Le noyau 3.2 a maintenant plus d'un an et demi. Si vous voulez jouer avec des systèmes de fichiers expérimentaux, vous voudrez peut-être exécuter un noyau plus à jour.
psusi

Réponses:

14

Eh bien, ce fut une expérience d'apprentissage pour moi, mais je l'ai finalement compris. J'expliquerai mon processus ici afin qu'il soit plus facile de savoir comment comprendre ces choses par vous-même (la documentation BTRFS, comme vous l'avez sûrement découvert, est relativement incomplète pour le moment).

Au début, je pensais que la création du sous-volume était un ioctlavec un gestionnaire qui ne vérifiait pas les capacités (ce qui pouvait ou non être un problème de sécurité selon qu'il y avait une logique), alors que sa suppression modifiait directement les métadonnées (et donc l'utilisateur peut avoir besoin CAP_SYS_RAWIOde travailler correctement).

Pour vérifier, j'ai ouvert le btrfs-utilscode source et voici ce que j'ai trouvé:

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

Eh bien, ce n'est pas utile, ce sont les deux ioctl (note intéressante: "snapshot" est souvent utilisé de manière interchangeable dans le code source avec "subvolume" pour une raison quelconque). Je suis donc allé au code source du noyau et j'ai trouvé les deux gestionnaires fs/btrfs/ioctl.c.

Finalement, je l'ai retracée jusqu'à btrfs_ioctl_snap_destroy()et sur la ligne 2116:

     if (!capable(CAP_SYS_ADMIN)){

Plus précisément, il s'agit d'une vérification s'ils n'ont pas la capacité mais s'ils l'ont, la logique passe directement à l'exécution de l'opération. Le corps de l'instruction if vérifie si c'est l'utilisateur régulier qui est le propriétaire de l'inode du sous- USER_SUBVOL_RM_ALLOWEDvolume et l' option BTRFS est activée, il continue d'exécuter le gestionnaire. S'ils n'ont pas non plus le gestionnaire ioctl se termine avec une erreur.

Il semble donc que la destruction d'un "instantané" (alias "sous-volume") nécessite généralement un utilisateur qui a CAP_SYS_ADMIN(ou pour USER_SUBVOL_RM_ALLOWEDêtre activé et l'utilisateur "possède" le sous-volume donné). Super, qu'en est-il de la création d'un instantané / volume?

Le gestionnaire de l'ioctl semble être btrfs_ioctl_snap_create()ce gestionnaire semble ne contenir aucun appel à capable()directement ou indirectement. Étant donné que c'est la principale façon dont l'accès est négocié, je suppose que la création de sous-volumes réussit toujours . Cela explique au niveau fonctionnel pourquoi vous voyez ce que vous voyez.

Je ne peux pas expliquer pourquoi cela est considéré comme souhaitable en dehors du cas d'utilisation principal de BTRFS étant avec un serveur avec un accès utilisateur restreint. Ce n'est pas suffisant mais je ne vois aucun code pour réellement arrêter l'opération. Si vous ne trouvez pas de réponse à la raison (et que vous vous souciez de l'avoir), vous devrez peut-être demander sur la liste de diffusion du noyau.

Conclusion

Ma recherche semble indiquer que n'importe qui peut créer des sous-volumes, mais pour supprimer un sous-volume, vous devez soit avoir, CAP_SYS_ADMINsoit avoir besoin de la vérité que l'utilisateur appelant est le propriétaire de l'inode de sous-volume et USER_SUBVOL_RM_ALLOWEDactivé.

La création de sous-volume n'a pas de sens, donc il me manque probablement une manière indirecte de refuser l'opération, car cela semble être un moyen facile de faire un système par DoS.

Remarque: je ne suis pas dans un endroit où je peux vérifier cette fonctionnalité, mais une fois rentré chez moi, je peux définir si la setcapmagie fonctionne comme cela prédit.

Bratchley
la source
La façon dont cela a du sens (en ce qui concerne votre préoccupation DoS) est si rmdirest autorisé sur des sous-volumes vides. Ensuite rm -r, fonctionnera de manière transparente. Malheureusement, le code n'a tout simplement pas été développé (encore). On dirait que quelqu'un a fait trois essais en 2010 et a ensuite abandonné :(. Spinics.net/lists/linux-btrfs/msg06499.html
sourcejedi
5

La suppression d'un sous-volume permet à quelqu'un de dissocier des fichiers qui ne lui appartiennent pas. À mon avis, les fichiers qu'un utilisateur privilégié écrit dans un emplacement choisi par un utilisateur moins privilégié sont un jeu équitable, mais la personne qui a contribué à la fonctionnalité de suppression non root n'était probablement pas suffisamment sûre de la sécurité et du contenu de cette sémantique. pour les soumettre en tant que nouvelle option de montage ( mount -o user_subvol_rm_allowed).

Gabriel
la source
1
Eh bien, étonnamment, sous UNIX®, vous pouvez facilement dissocier un fichier que vous ne possédez pas - il vous suffit d'avoir une autorisation d'écriture dans son répertoire.
poige
J'ai le même problème sur Fedora 20, j'ai / home dans un sous-volume, j'utilise la racine utilisateur, mais de toute façon, je ne peux pas supprimer / home
c4f4t0r
poige, si le fichier en question se trouve dans un dossier qui ne vous appartient pas, vous ne pouvez pas le dissocier et vous ne pouvez pas dissocier le dossier lui-même car il contient toujours des éléments. Vous ne pouvez effectuer que des opérations non destructives sur ce dossier, comme le déplacer ou le renommer.
sleblanc
-1

"Impossible de supprimer / home" (qui est @home).

Pourquoi voudriez-vous supprimer le sous-volume sur lequel réside votre / home / compte, sauf si vous avez créé un snapshot / home_snapshot_yymmdd pour remplacer / home par?

Je suis nouveau dans l'utilisation de btrfs, mais voici ce que j'ai découvert: @ / et @home (/ et / home) sont créés par btrfs lorsqu'il est installé sur votre disque dur en tant que système de fichiers. À moins que vous ne fassiez une restauration de / home à partir d'un instantané précédent, si je comprends bien, vous vous couperiez à genoux.

Cependant, vous pouvez monter le périphérique sur lequel / home se trouve, AS ROOT, en utilisant mount / dev / sa / mnt / (ou le périphérique sur lequel votre système btrfs est en cours d'exécution). @Accueil. Ensuite, vous pouvez utiliser la commande mv pour déplacer @home_snapshot_yymmdd (ou ce que vous avez nommé) vers @home. Le déménagement peut prendre des heures, selon la taille de @home. Ensuite, retournez le CD sur votre propre compte et lancez sudo umount / mnt / Vous n'avez jamais vraiment vous déconnecter ni arrêter votre système. C'est une beauté de btrfs.

GreyGeek
la source
Semble qu'ils l'ont déjà fait. Btrfs ne fait pas @ et @home à moins que vous ne le leur disiez (ou que votre distribution comme Ubuntu le fasse pour vous).
Anthon