일반 사용자가 btrfs 하위 볼륨을 삭제할 수 없는 이유

일반 사용자가 btrfs 하위 볼륨을 삭제할 수 없는 이유

루프에 마운트된 사용자 생성 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@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커널, btrfs-tools에서 여전히 발생합니다.v0.20-rc1

답변1

글쎄, 그것은 나에게 학습 경험이었지만 마침내 그것을 얻었습니다. 이러한 문제를 직접 해결하는 방법을 더 쉽게 알 수 있도록 여기에서 내 프로세스를 설명하겠습니다. (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 문의 본문에서는 하위 볼륨 inode의 소유자가 일반 사용자인지 확인하고 USER_SUBVOL_RM_ALLOWEDBTRFS 옵션이 활성화된 후에도 핸들러 실행이 계속됩니다. 아무것도 없으면 ioctl 핸들러는 오류와 함께 종료됩니다.

CAP_SYS_ADMIN따라서 "스냅샷"(일명 "하위 볼륨")을 삭제하려면 일반적으로 사용자 소유권 (또는 USER_SUBVOL_RM_ALLOWED특정 하위 볼륨을 활성화하고 사용자가 "소유")이 필요한 것처럼 보입니다 . 좋습니다. 스냅샷/볼륨을 생성해 보는 것은 어떻습니까?

ioctl 처리기는 btrfs_ioctl_snap_create()직접 또는 간접 호출을 포함하지 않는 것으로 보입니다 capable(). 이것이 프록시 액세스가 수행되는 기본 방법이므로 하위 볼륨 생성을 의미한다고 가정합니다.언제나효과가 있었습니다. 이는 기능적 수준에서 당신이 보는 것을 보는 이유를 설명합니다.

나는 말을 할 수 없다이는 BTRFS의 주요 사용 사례(즉, 사용자 액세스가 제한된 서버)를 제외하고는 바람직한 것으로 간주됩니다. 충분하지는 않지만 실제로 작업을 중지하는 코드가 표시되지 않습니다. 이유에 대한 답을 찾을 수 없다면(그리고 그것을 얻고 싶다면) 커널 메일링 리스트에 물어볼 수도 있습니다.

결론적으로

내 연구에 따르면 누구나 하위 볼륨을 생성할 수 있지만 하위 볼륨을 삭제하려면 하위 볼륨을 소유하거나 CAP_SYS_ADMIN호출하는 사용자가 하위 볼륨 inode의 소유자가 되어 USER_SUBVOL_RM_ALLOWED이를 활성화해야 합니다.

하위 볼륨을 생성하는 것은 의미가 없으므로 작업을 거부하는 간접적인 방법이 누락되었을 수 있습니다. 이는 시스템에 DoS를 수행하는 쉬운 방법인 것 같습니다.

참고: 이 기능을 확인할 수는 없지만 집에 도착하면 setcap예상대로 작동하도록 마법을 설정할 수 있습니다.

답변2

하위 볼륨을 삭제하면 다른 사람이 자신에게 속하지 않은 파일의 링크를 해제할 수 있습니다. 권한이 낮은 사용자가 선택한 위치에 권한이 있는 사용자가 작성한 파일은 제 생각에는 공정한 게임이지만 루트가 아닌 삭제 기능에 기여하는 사람은 해당 파일을 새로운 것으로 취급할 만큼 이러한 의미의 보안 및 내용에 대해 충분히 확신하지 못할 수 있습니다. 제출된 ( mount -o user_subvol_rm_allowed).

답변3

"/home을 삭제할 수 없습니다"(예: @home).

/home을 대체하기 위해 /home_snapshot_yymmdd 스냅샷을 생성하지 않은 경우 /home/ 계정이 있는 하위 볼륨을 삭제하는 이유는 무엇입니까?

저는 btrfs를 처음 사용하지만 제가 찾은 내용은 다음과 같습니다. @/ 및 @home(/ 및 /home)은 btrfs가 하드 드라이브에 파일 시스템으로 마운트될 때 btrfs에 의해 생성됩니다. 내가 이해한 바에 따르면 이전 스냅샷에서 /home을 복원하지 않는 한 정체됩니다.

그러나 mount /dev/sa /mnt/(또는 btrfs 시스템이 실행 중인 모든 항목)를 사용하여 /home이 ROOT로 있는 장치를 마운트한 다음 /mnt/로 CD를 이동하고 거기에서 @home 삭제 명령을 실행할 수 있습니다. 그런 다음 mv 명령을 사용하여 @home_snapshot_yymmdd(또는 원하는 이름으로 지정)를 @home으로 이동할 수 있습니다. @home의 크기에 따라 이동하는 데 몇 시간이 걸릴 수 있습니다. 그런 다음 CD를 자신의 계정으로 다시 넣고 sudo umount /mnt/를 실행하십시오. 실제로는 로그아웃하거나 시스템을 종료하지 않습니다. 이것이 btrfs의 아름다움입니다.

관련 정보