通常のユーザーがbtrfsサブボリュームを削除できないのはなぜですか


12

ループマウントされたユーザーが作成したbtrfsファイルシステムを使用して、権限を正しく設定すると、ユーザーはbtrfsサブボリュームを自由に作成できます。

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

ただし、新しく作成されたサブボリュームを削除しようとすると、エラーが発生します。

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'

もちろん、rootユーザーはそれを削除できます:

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

作成操作と削除操作のこの動作の違いは少し奇妙に思えます。誰もこれに光を当てることができますか?

コマンドの正確なシーケンスは次のとおりです。

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

権限は次のとおりです。

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

そして、関連する行df -T

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

ディストリビューションはDebian Wheezy、3.2.0-4-686-paeカーネル、v0.19btrfs-toolsです。この状況は、Ubuntu Saucy、3.11.0-4-genericカーネル、v0.20-rc1btrfs-toolsで引き続き発生します。


私の理解では、このファイルシステムタイプはまだ実験段階であり、本番環境では使用できません。
mdpc

df -Tand の出力を追加できますbtrfs versionか?同じことを試みたときに、次のエラーが表示されました。「エラー:サブボリュームを作成できません-許可が拒否されました」
-bsd

@mdpcそれは本当ですが、btrfsは数年前から存在しており、この段階ではある程度安定していると予想されます。この時点で、これがバグなのか「機能」なのかを理解することは依然として有用かもしれません。
goncalopp

@bdowningコマンドの正確なシーケンス、df、および使用したバージョンを追加しました。
goncalopp

3.2カーネルは現在1年半以上経過しています。実験的なファイルシステムを使用したい場合は、最新のカーネルを実行することをお勧めします。
psusi

回答:


14

まあ、これは私にとって学習経験でしたが、私は最終的にそれを理解しました。ここで自分のプロセスを説明して、自分でこのことを理解する方法を簡単に理解できるようにします(BTRFSのドキュメントは、現時点では比較的不完全です)。

最初は、サブボリュームの作成はioctl機能チェックを行わないハンドラーであると考えました(何らかのロジックがあるかどうかに応じてセキュリティ問題であるかどうかは不明です)が、削除するとメタデータが直接変更されます(したがって、ユーザーはCAP_SYS_RAWIO適切に作業する必要があります)。

確認するために、btrfs-utilsソースコードをクラックして開きましたが、これが見つかりました。

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

まあ、それは役に立たない、両方とも ioctlである(興味深い副次注:「スナップショット」はしばしばソースコードで「サブボリューム」と何らかの理由で互換的に使用される)。だから私はカーネルのソースコードに行き、両方のハンドラーを見つけましたfs/btrfs/ioctl.c

最終的に、私はそれをbtrfs_ioctl_snap_destroy()2116行目まで追跡しました。

     if (!capable(CAP_SYS_ADMIN)){

具体的には、これは機能がないかどうかのチェックですが、機能がある場合は、ロジックがスキップして操作を実行します。ifステートメントの本体は、サブボリュームのiノードの所有者であり、USER_SUBVOL_RM_ALLOWEDBTRFSオプションが有効になっている通常のユーザーであるかどうかを確認して、ハンドラーの実行を継続します。ioctlハンドラーがない場合、エラーで終了します。

そのため、「スナップショット」(別名「サブボリューム」)を破壊するには、一般にCAP_SYS_ADMIN(またはUSER_SUBVOL_RM_ALLOWED有効にするために特定のサブボリュームを「所有」する)ユーザーが必要です。素晴らしい、スナップショット/ボリュームの作成はどうですか?

ioctlのハンドラーは、btrfs_ioctl_snap_create()このハンドラーにはcapable()直接または間接的な呼び出しが含まれていないようです。これがアクセスが仲介される主な方法であるため、サブボリュームの作成が常に成功することを意味します。これは、機能レベルで、表示されているものが表示されている理由を説明しています。

ユーザーアクセスが制限されているサーバーを使用するというBTRFSの主なユースケース以外ではこれが望ましいと考えられる理由について話すことはできません。それでは十分ではありませんが、実際に操作を停止するコードは表示されません。その理由に対する答えが見つからない場合(そして、あなたがそれを持っていることを気にかけている場合)、カーネルメーリングリストで質問する必要があるかもしれません。

結論

私の研究では、だれでもサブボリュームを作成できるが、必要なサブボリュームを削除するにCAP_SYS_ADMINは、呼び出しユーザーがサブボリュームiノードの所有者であり、USER_SUBVOL_RM_ALLOWED有効になっている必要があることを示しているようです。

サブボリュームの作成は意味をなさないので、システムをDoSする簡単な方法のように思えるので、おそらく操作を拒否する間接的な方法を見逃しています。

注:この機能を検証できる場所にいるわけではありませんが、家に着いたらsetcap、これが予測する方法でマジックが機能するかどうかを設定できます。


rmdir空のサブボリュームで許可されている場合は(DoSの懸念に関して)理にかなっています。その後、rm -r透過的に動作します。残念ながら、コードは(まだ)開発されていません。誰かが2010年に3回試行してからあきらめたようです:(。spinics.net/lists/linux-btrfs/msg06499.html
sourcejedi

5

サブボリュームを削除すると、誰かが所有していないファイルのリンクを解除できます。私の意見では、特権ユーザーがあまり特権のないユーザーによって選択された場所に書き込むファイルは公正なゲームですが、非ルート削除機能に貢献した人はおそらく、それらのセマンティクスがどれほど安全でコンテンツであるかについて十分に自信を持っていませんでした新しいマウントオプション(mount -o user_subvol_rm_allowed)として送信します。


1
驚くべきことに、UNIX®では、所有していないファイルのリンクを簡単に解除できます。ディレクトリの書き込み権限が必要なだけです。
poige

fedora 20でも同じ問題があり、サブボリュームに/ homeがあり、ユーザーrootを使用していますが、とにかく/ homeを削除できません
c4f4t0r 14年

poige、問題のファイルがあなたが所有していないフォルダにある場合、あなたはそれをリンク解除することはできず、フォルダの中にまだ物が含まれているのでフォルダ自体をリンク解除することはできません。このフォルダでは、移動や名前の変更など、非破壊的な操作のみを行うことができます。
sleblanc

-1

「/ homeを削除できません」(@home)。

/ homeを置き換える/ home_snapshot_yymmddスナップショットを作成していない限り、なぜ/ home /アカウントが存在するサブボリュームを削除するのですか?

私はbtrfsを使用するのは初めてですが、これは私が見つけたものです:@ /および@home(/および/ home)は、ファイルシステムとしてHDにインストールされるときにbtrfsによって作成されます。以前のスナップショットから/ homeの復元を行っていない限り、私が理解しているように、あなたはひざまずいています。

ただし、mount / dev / sa / mnt /(または実行中のbtrfsシステムのデバイス)を使用して、/ homeがオンのデバイスをAS ROOTとしてマウントできます。次に、/ mnt /にcdし、そこからdeleteコマンドを発行します@home。次に、mvコマンドを使用して@home_snapshot_yymmdd(または名前を付けたもの)を@homeに移動できます。@homeのサイズによっては、移動に数時間かかる場合があります。次に、CDを自分のアカウントに戻し、sudo umount / mnt /を発行します。システムを実際にログアウトまたはシャットダウンしたことはありません。それはbtrfsの美しさです。


彼らはすでにそうしているようです。Btrfsは、ユーザーに指示しない限り、@と@homeを作成しません(またはUbuntuのようなディストリビューションがあなたのためにそれを行います)。
アントン14年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.