एक नियमित उपयोगकर्ता एक 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

डिस्ट्रो एक डेबियन व्हीज़ी, 3.2.0-4-686-paeकर्नेल, v0.19ट्रॉट्स-टूल्स है। स्थिति अभी भी Ubuntu Saucy, 3.11.0-4-genericकर्नेल, v0.20-rc1btrfs-tools पर होती है।


मेरी समझ से यह फाइलसिस्टम प्रकार अभी भी प्रायोगिक है और उत्पादन तैयार नहीं है।
mdpc

क्या आप df -Tऔर का आउटपुट जोड़ सकते हैं btrfs version? जब मैंने वही कोशिश की तो मुझे निम्नलिखित त्रुटि मिली "त्रुटि: सबवोल्यूम नहीं बना सकता - अनुमति से इनकार किया"
bsd

@ mdpc हालांकि यह सच है, कुछ वर्षों के लिए btrfs लगभग हो गया है, और इस स्तर पर कुछ हद तक स्थिर होने की उम्मीद है। यह समझना अभी भी उपयोगी हो सकता है कि क्या यह एक बग या 'फीचर' है, इस बिंदु पर।
गोनोकॉप्ट

@bdowning मैंने कमांड, df और मेरे द्वारा उपयोग किए गए संस्करणों का सटीक अनुक्रम जोड़ा है।
जोंकॉपॉप

3.2 कर्नेल अब एक वर्ष से अधिक पुराना है। यदि आप प्रायोगिक फाइलसिस्टम के साथ खेलना चाहते हैं, तो आप कर्नेल को अधिक चलाना चाहते हैं।
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)){

विशेष रूप से, यह एक जांच है यदि उनके पास क्षमता नहीं है लेकिन अगर उनके पास यह है, तो तर्क सीधे ऑपरेशन करने के लिए छोड़ देता है। यदि यह विवरण देखने वाला शरीर यह देखता है कि क्या यह नियमित उपयोगकर्ता है, जो सबवोल्यूम इनोड का मालिक है और USER_SUBVOL_RM_ALLOWEDBTRFS विकल्प सक्षम है, तो यह हैंडलर को निष्पादित करना जारी रखता है। यदि उनके पास या तो ioctl हैंडलर एक त्रुटि के साथ बाहर नहीं निकलता है।

तो ऐसा लगता है कि एक "स्नैपशॉट" (उर्फ "सबवोल्यूम") को नष्ट करने के लिए आम तौर पर एक उपयोगकर्ता की आवश्यकता होती है CAP_SYS_ADMIN(या USER_SUBVOL_RM_ALLOWEDसक्षम होने के लिए और उपयोगकर्ता "दिए गए सबवोल्यूम का मालिक है")। महान, एक स्नैपशॉट / वॉल्यूम बनाने के बारे में क्या?

Ioctl के लिए हैंडलर प्रतीत होता है कि btrfs_ioctl_snap_create()यह हैंडलर capable()प्रत्यक्ष या अप्रत्यक्ष रूप से कोई कॉल नहीं करता है । चूँकि यह मुख्य तरीका है कि ब्रोकरी का उपयोग किया जाता है, इसलिए मैं इसका अर्थ यह ले रहा हूँ कि सबवोल्यूम निर्माण हमेशा सफल होता है। यह एक कार्यात्मक स्तर पर बताता है कि आप जो देख रहे हैं उसे क्यों देख रहे हैं।

मैं यह नहीं कह सकता कि BTRFS के मुख्य उपयोग के मामले में यह प्रतिबंधित क्यों माना जाता है, जिसमें प्रतिबंधित उपयोगकर्ता पहुँच वाला सर्वर है। यह पर्याप्त नहीं है, लेकिन मैं वास्तव में ऑपरेशन को रोकने के लिए कोई कोड नहीं देख रहा हूं। अगर आपको इसका जवाब नहीं मिल रहा है कि ऐसा क्यों है (और आपको इसकी परवाह है) तो आपको कर्नेल मेलिंग सूची पर पूछना पड़ सकता है।

निष्कर्ष

मेरे शोध से संकेत मिलता है कि कोई भी व्यक्ति सबवॉल्म बना सकता है, लेकिन एक सबवोल्यूम को हटाने के लिए आपको या तो इसकी आवश्यकता है CAP_SYS_ADMINया इसे दोनों की सही आवश्यकता है कि कॉलिंग उपयोगकर्ता सबवूलेशन इनोड का मालिक है और USER_SUBVOL_RM_ALLOWEDसक्षम है।

सबवोल्यूम निर्माण का कोई मतलब नहीं है इसलिए मुझे शायद कुछ अप्रत्यक्ष तरीके याद आ रहे हैं जो कि ऑपरेशन से वंचित हैं क्योंकि ऐसा लगता है कि एक सिस्टम DoS का आसान तरीका है।

नोट: मैं ऐसी जगह नहीं हूं, जहां मैं इस कार्यक्षमता को सत्यापित कर सकूं, लेकिन एक बार घर पहुंचने के बाद मैं यह निर्धारित कर सकता हूं कि क्या setcapजादू काम करता है।


जिस तरह से यह समझ में आता है (आपकी DoS चिंता के बारे में) अगर rmdirखाली सबवूल्स पर अनुमति है। फिर rm -rपारदर्शी तरीके से काम करेंगे। दुर्भाग्य से कोड बस (अभी तक) विकसित नहीं किया गया था। ऐसा लगता है कि किसी ने 2010 में तीन कोशिशें कीं और फिर हार मान ली
sourcejedi

5

एक सबवोल्यूम को हटाने से किसी को उन फ़ाइलों को अनलिंक करने की अनुमति मिलती है जो उनके पास नहीं हैं। मेरी राय में, कम विशेषाधिकार प्राप्त उपयोगकर्ता द्वारा चुने गए स्थान पर एक विशेषाधिकार प्राप्त उपयोगकर्ता द्वारा लिखी गई फाइलें उचित खेल हैं, लेकिन गैर-रूट विलोपन की कार्यक्षमता में योगदान करने वाले व्यक्ति को शायद इस बात पर विश्वास नहीं हुआ कि वे शब्दार्थ कितने सुरक्षित थे और सामग्री उन्हें नए माउंट विकल्प के रूप में सबमिट करने के लिए ( mount -o user_subvol_rm_allowed)।


1
ठीक है, आश्चर्यजनक रूप से UNIX® में आप आसानी से एक फ़ाइल को अनलिंक कर सकते हैं जो आपके पास नहीं है - आपको इसकी निर्देशिका में अनुमति लिखने की आवश्यकता है।
पोइज

मुझे फ़ेडोरा 20 पर समान समस्या है, मेरे पास / घर में एक सबवोल्यूम है, मैं उपयोगकर्ता रूट का उपयोग कर रहा हूं, लेकिन किसी भी तरह, मैं डिलीट / होम नहीं कर सकता
c4f4t0r

poige, यदि विचाराधीन फ़ाइल एक फ़ोल्डर में है जो आपके पास नहीं है, तो आप इसे अनलिंक नहीं कर सकते हैं और आप फ़ोल्डर को स्वयं अनलिंक नहीं कर सकते क्योंकि इसमें अभी भी सामान है। आप केवल इस फ़ोल्डर पर गैर-विनाशकारी संचालन कर सकते हैं, जैसे इसे स्थानांतरित करना या इसका नाम बदलना।
स्लीपब्लैंक

-1

"नहीं हटा सकते / घर" (जो @home है)।

जब तक आपने / home_snapshot_yymmdd स्नैपशॉट नहीं बनाया है, तब तक आप उस सबवूलेम को डिलीट क्यों करना चाहेंगे जिस पर आपका / होम / अकाउंट रहता है?

मैं btrfs का उपयोग करने के लिए नया हूँ, लेकिन यह वही है जो मुझे पता चला है: @ / और @home (/ और / home) btrfs द्वारा बनाए जाते हैं जब यह आपके HD पर फ़ाइल सिस्टम के रूप में स्थापित होता है। जब तक आप पिछले स्नैपशॉट से / होम की पुनर्स्थापना नहीं कर रहे हैं, जैसा कि मैं समझता हूं, आप अपने घुटनों पर खुद को काट लेंगे।

हालाँकि, आप उस डिवाइस को माउंट कर सकते हैं जो / होम ऑन है, AS ROOT, माउंट / देव / sa / mnt / (या जो कभी आपके रनिंग btrfs सिस्टम को डिवाइस करता है) का उपयोग करके फिर cd से / mnt / और वहां से डिलीट कमांड जारी करें @घर। फिर आप @home को @home_snapshot_yymmdd (या जिसे आपने कभी नाम दिया है) स्थानांतरित करने के लिए mv कमांड का उपयोग कर सकते हैं। @Home के आकार के आधार पर इस कदम में घंटों लग सकते हैं। फिर अपने खाते में वापस सीडी और sudo umount / mnt जारी करें / आपने वास्तव में लॉगआउट नहीं किया है या अपना सिस्टम बंद नहीं किया है। यह btrfs की सुंदरता है।


ऐसा लगता है कि वे पहले से ही ऐसा कर चुके हैं। Btrfs तब तक @ और @home नहीं बनाते हैं जब तक कि आप उन्हें नहीं बताते (या उबंटू की तरह आपका डिस्ट्रो आपके लिए ऐसा करता है)।
एंथन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.