일반 사용자가 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@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

배포판은 데비안 Wheezy, 3.2.0-4-686-pae커널, v0.19btrfs-tools입니다. 상황은 여전히 ​​우분투 소스, 3.11.0-4-generic커널, v0.20-rc1btrfs-tools 에서 발생 합니다.


내 이해 로이 파일 시스템 유형은 여전히 ​​실험적이며 프로덕션 준비가되지 않았습니다.
mdpc

df -T및 의 출력을 추가 할 수 있습니까 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입니다 (흥미로운 쪽지 : "스냅 샷"은 종종 어떤 이유로 "subvolume"과 소스 코드에서 상호 교환 적으로 사용됩니다). 그래서 커널 소스 코드로 가서에서 두 핸들러를 모두 찾았습니다 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마술이 어떻게 작동하는지 예측할 수 있습니다.


rmdir비어있는 하위 볼륨에서 허용되는 경우 (DoS 문제와 관련하여) 의미가 있습니다. 그런 다음 rm -r투명하게 작동합니다. 불행히도 코드는 아직 개발되지 않았습니다 (아직). 그것은 사람이 2010 년에 세 번을 만든 다음 :( 포기 것 같습니다. spinics.net/lists/linux-btrfs/msg06499.html
sourcejedi

5

하위 볼륨을 삭제하면 누군가 소유하지 않은 파일의 링크를 해제 할 수 있습니다. 내 의견으로는, 권한이없는 사용자가 선택한 위치에 권한있는 사용자가 작성하는 파일은 공정한 게임이지만 루트가 아닌 삭제 기능을 제공 한 사람은 그 의미가 얼마나 안전하고 만족 스러운지에 대해 충분히 확신하지 못했을 것입니다 새로운 마운트 옵션 ( mount -o user_subvol_rm_allowed) 으로 제출하십시오 .


1
놀랍게도 UNIX®에서는 소유하지 않은 파일을 쉽게 연결 해제 할 수 있습니다. 디렉토리에 대한 쓰기 권한 만 있으면됩니다.
poige

나는, 내가 사용자 루트를 사용하고 난 서브 볼륨에 / 홈을 가지고, 페도라 20에 동일한 문제가 있지만 anyaway, 난 / 가정을 삭제할 수 없습니다
c4f4t0r

poige, 문제의 파일이 자신이 소유하지 않은 폴더에 있으면 링크를 해제 할 수 없으며 폴더에 여전히 내용이 들어 있으므로 폴더 자체를 링크 해제 할 수 없습니다. 이 폴더를 이동하거나 이름을 바꾸는 등 비파괴적인 작업 만 수행 할 수 있습니다.
sleblanc

-1

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

/ home을 대체하기 위해 / home_snapshot_yymmdd 스냅 샷을 만들지 않은 경우 왜 / home / 계정이있는 하위 볼륨을 삭제 하시겠습니까?

btrfs를 처음 사용하지만 이것이 내가 찾은 것입니다 : @ / 및 @home (/ 및 / home)은 btrfs가 파일 시스템으로 HD에 설치 될 때 btrfs에 의해 생성됩니다. 이전 스냅 샷에서 / home을 복원하지 않는 한, 내가 알기로는 무릎을 꿇을 것입니다.

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


그들은 이미 그렇게 한 것 같습니다. Btrfs는 @와 @home을 만들지 않으면 (또는 Ubuntu와 같은 배포판이 대신하지 않습니다).
Anthon
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.