มีไฟล์ที่มีอยู่เสมอและผู้ใช้ 'ปกติ' ไม่สามารถ lstat ได้หรือไม่


14

ฉันต้องการสิ่งนี้สำหรับการทดสอบหน่วย มีฟังก์ชันที่ทำlstatบนพา ธ ไฟล์ที่ส่งผ่านเป็นพารามิเตอร์ ฉันต้องเรียกใช้เส้นทางรหัสที่lstatล้มเหลว (เพราะครอบคลุมรหัสได้ถึง 90%)

การทดสอบสามารถทำงานภายใต้ผู้ใช้คนเดียวได้ดังนั้นฉันจึงสงสัยว่ามีไฟล์ใน Ubuntu ที่มีอยู่เสมอหรือไม่ แต่ผู้ใช้ทั่วไปไม่มีสิทธิ์อ่านเพื่ออ่านหรือไปยังโฟลเดอร์ของมัน (ดังนั้นlstatจะล้มเหลวหากไม่ดำเนินการในฐานะรูท)

ไฟล์ที่ไม่มีอยู่ไม่ใช่วิธีการแก้ปัญหาเนื่องจากมีเส้นทางรหัสแยกต่างหากสำหรับสิ่งที่ฉันเรียกแล้ว

แก้ไข: การขาดการเข้าถึงเพื่ออ่านไฟล์เท่านั้นไม่เพียงพอ ด้วยที่lstatยังคงสามารถดำเนินการได้ ฉันสามารถทริกเกอร์ได้ (บนเครื่องโลคัลของฉันซึ่งฉันมีสิทธิ์เข้าถึงรูท) โดยการสร้างโฟลเดอร์ใน / root และไฟล์ในนั้น และตั้งค่าการอนุญาต 700 ในโฟลเดอร์ ดังนั้นฉันกำลังค้นหาไฟล์ที่อยู่ในโฟลเดอร์ที่เข้าถึงได้โดยรูทเท่านั้น


6
IMHO/etc/shadow
Romeo Ninov

3
คุณไม่สามารถสมมติว่ามีไฟล์ใด ๆ อยู่เนื่องจากโปรแกรมของคุณอาจทำงานใน chroot หรือ namespace แยกต่างหาก หากสมมติว่า / proc ถูกเมาต์เป็น OK และ init ไม่มีอะไรพิเศษ/proc/1/fd/0ควรทำ
mosvy

1
@mosvy ขอบคุณที่ใช้กับเครื่องของฉัน หืมมมฉันจะลองใช้ใน QA และ Staging pool ด้วย
หมอบลูกแมว

2
ทำไมคุณถึงผูกรหัสการทดสอบของคุณกับรสชาติของระบบปฏิบัติการเฉพาะเมื่อคุณสามารถสร้างไฟล์ทิ้งและลบการเข้าถึงการอ่านของคุณเอง?
Kilian Foth

4
ฉันยืนยันว่ามันไม่ได้เป็นการทดสอบหน่วยเมื่อเริ่มต้นขึ้นอยู่กับระบบไฟล์ของจริงแทนที่จะล้อเลียน
Toby Speight

คำตอบ:


21

บนระบบ Linux ที่ทันสมัยคุณควรจะสามารถใช้/proc/1/fdinfo/0(ข้อมูลสำหรับ file descriptor 1 (stdout) ของกระบวนการของ id 1 ( initในรูท pid เนมสเปซซึ่งควรจะทำงานตามroot)

คุณสามารถค้นหารายการด้วย (ในฐานะผู้ใช้ปกติ):

sudo find /etc /dev /sys /proc -type f -print0 |
  perl -l -0ne 'print unless lstat'

(ลบ-type fหากคุณไม่ต้องการ จำกัด ไฟล์ปกติ)

/var/cache/ldconfig/aux-cacheเป็นตัวเลือกที่เป็นไปได้อีกอย่างหนึ่งหากคุณเพียงต้องการพิจารณาระบบ Ubuntu มันควรทำงานบนระบบ GNU ส่วนใหญ่ตามที่/var/cache/ldconfigสร้างอ่าน + เขียน + ค้นหาเพื่อรูทโดยldconfigคำสั่งที่มาพร้อมกับ GNU libc เท่านั้น


1
ขอบคุณ! หาก/proc/1/fdinfo/0ทำงานบน Ubuntu 16.04 และ 18.04 นั่นก็เพียงพอแล้ว
หมอบลูกแมว

1
การใช้/proc/1/fdinfo/0ไม่จำเป็นต้องทำงานในคอนเทนเนอร์ (เช่นคอนเทนเนอร์ Docker) และบ่อยครั้งที่การทดสอบหน่วยถูกเรียกใช้ในคอนเทนเนอร์ดังกล่าวใน CI
Philipp Wendler

@PhilippWendler ฉันได้พูดถึงรูต pid รูทเรียบร้อยแล้ว OP ไม่ได้ถามเกี่ยวกับคอนเทนเนอร์ แต่เกี่ยวกับไฟล์ที่รับประกันว่าจะมีอยู่ในเค้าโครงระบบไฟล์ของระบบ Ubuntu เนื่องจากคอนเทนเนอร์อาจมีไฟล์และเค้าโครงไดเรคทอรีคำถามจึงไม่สามารถตอบได้
Stéphane Chazelas

12

การดูหน้าคนlstat (2)คุณสามารถรับแรงบันดาลใจในบางกรณีที่อาจทำให้มันล้มเหลวโดยมีข้อผิดพลาดนอกเหนือจาก ENOENT (ไฟล์ไม่มีอยู่)

สิ่งที่ชัดเจนที่สุดคือ:

EACCES ค้นหาได้รับอนุญาตถูกปฏิเสธสำหรับหนึ่งในไดเรกทอรีในคำนำหน้าเส้นทางของเส้นทาง

ดังนั้นคุณต้องการไดเรกทอรีที่คุณไม่สามารถค้นหาได้

ใช่คุณสามารถค้นหาสิ่งที่มีอยู่แล้วในระบบของคุณ (อาจเป็น/var/lib/privateถ้ามีอยู่แล้ว) แต่คุณก็สามารถสร้างตัวเองขึ้นมาได้ด้วยเทียบเท่ากับ:

$ mkdir myprivatedir
$ touch myprivatedir/myunreachablefile
$ chmod 0 myprivatedir
$ ls -l myprivatedir/myunreachablefile

การดำเนินการ lstat (2) จะล้มเหลวด้วย EACCES ที่นี่ (การลบสิทธิ์ทั้งหมดออกจากไดเรกทอรีช่วยให้มั่นใจได้ว่าคุณอาจไม่ต้องการจำนวนมากและchmod -xการลบการอนุญาตให้ใช้งานก็เพียงพอแล้วเนื่องจากจำเป็นต้องใช้สิทธิ์ในการเรียกใช้ไดเรกทอรีเพื่อเข้าถึงไฟล์ที่อยู่ด้านล่าง)

มีอีกวิธีที่สร้างสรรค์ในการทำให้ lstat (2) ล้มเหลวโดยดูที่หน้าคู่มือ:

ENOTDIR ส่วนประกอบของคำนำหน้าเส้นทางของเส้นทางไม่ใช่ไดเรกทอรี

ดังนั้นการพยายามเข้าถึงไฟล์เช่น/etc/passwd/nonexistentควรทริกเกอร์ข้อผิดพลาดนี้ซึ่งแตกต่างจาก ENOENT ("ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว") และอาจเหมาะสมกับความต้องการของคุณ

อีกหนึ่งคือ:

เส้นทางENAMETOOLONGยาวเกินไป

แต่คุณอาจต้องการชื่อยาวมากสำหรับอันนี้ (ฉันเชื่อว่า 4,096 ไบต์เป็นขีด จำกัด ปกติ แต่ระบบ / ระบบไฟล์ของคุณอาจมีชื่อยาวกว่านี้)

สุดท้ายมันยากที่จะบอกได้ว่าสิ่งเหล่านี้จะเป็นจริงมีประโยชน์สำหรับคุณ คุณบอกว่าคุณต้องการบางสิ่งบางอย่างที่ไม่ก่อให้เกิดสถานการณ์ "ไม่มีไฟล์" แม้ว่าโดยทั่วไปแล้วจะหมายถึงข้อผิดพลาด ENOENT แต่ในทางปฏิบัติการตรวจสอบระดับสูงขึ้นจำนวนมากจะตีความข้อผิดพลาดใด ๆ จาก lstat (2) ว่า "ไม่มีอยู่" ตัวอย่างเช่นtest -eหรือเทียบเท่า[ -e ...]จากเปลือกอาจเพียงแค่ตีความทั้งหมดข้างต้นเป็น "ไม่มีอยู่" โดยเฉพาะอย่างยิ่งเนื่องจากมันไม่มีวิธีที่ดีในการส่งคืนข้อความแสดงข้อผิดพลาดที่แตกต่างกันและไม่ส่งคืนข้อผิดพลาดจะบ่งบอกถึงไฟล์ที่มีอยู่ ซึ่งแน่นอนที่สุดไม่ใช่กรณี


@StephaneChazelas เยี่ยมมาก! Updated
filbranden

6

คุณทำได้findด้วยตัวเอง

การใช้/etc- ไดเร็กทอรีไฟล์คอนฟิกูเรชันเป็นจุดเริ่มต้น:

sudo find /etc -type f -perm 0400 -user root

ในระบบของฉันสิ่งนี้จะไม่ส่งคืนสิ่งใด

คุณสามารถ จำกัด ได้น้อยกว่าและอนุญาตให้กลุ่มroot(ผู้ใช้rootควรเป็นสมาชิกของกลุ่มเท่านั้นroot) และระวังการอนุญาต440:

sudo find /etc -perm 0440 -user root -group root

ในระบบของฉันผลตอบแทนนี้:

/etc/sudoers.d/README
/etc/sudoers

แก้ไข:

จากการแก้ไขของคุณคุณกำลังมองหาไดเรกทอรีที่ไม่มีสิทธิ์เพียงพอสำหรับผู้ใช้ที่เรียกใช้เพื่อป้องกันรายการไดเรกทอรี:

sudo find / -perm o-rwx -type d -user root -group root 

นี่ฉันกำลังมองหาไดเรกทอรี ( -type d) ที่ขาดอ่านเขียน-รันบิตดัดสำหรับคนอื่น ๆ ( o-rwx) root:rootและเป็นเจ้าของโดย

ในทางเทคนิคแล้วxบิตที่ไม่มีอยู่ของ execute ( ) บิตจะป้องกันการแสดงรายการไดเรกทอรี ( lstat(2)) ในไดเรกทอรี

ในผลลัพธ์ที่ฉันพบ/run/systemd/inaccessible/ในระบบพื้นฐานของฉัน Systemd init

เกี่ยวกับไฟล์ใน/proc, /sys, /dev:

  • ระบบไฟล์เหล่านี้คือ FS เสมือนจริงซึ่งอยู่ในหน่วยความจำไม่ใช่ในดิสก์

  • หากคุณวางแผนที่จะพึ่งพา/procใช้/proc/1/เช่นพึ่งพาสิ่งที่อยู่ภายใต้ PID 1 ไม่ใช่ PID ใด ๆ ในภายหลังที่จะมีความน่าเชื่อถือ / ความสอดคล้องเนื่องจาก PID (กระบวนการ) ในภายหลังจะไม่รับประกันว่าจะมีอยู่จริง


ขอบคุณฉันคิดว่าคำถามของฉันผิด ฉันยังคงสามารถ lstat ไฟล์โดยไม่ต้องอ่านเพื่อเข้าถึงพวกเขา อาจจะมีการ จำกัด การเข้าถึงโฟลเดอร์? (ฉันแก้ไขชื่อ)
Crouching Kitten

ขอบคุณ เมื่อfind / -type d -perm 0400 -user rootฉันพบไดเรกทอรี/proc/20/map_files/แล้วถ้าฉันอ้างถึงชื่อไฟล์ที่สร้างขึ้นภายในโฟลเดอร์/proc/20/map_files/asdasdนั้นมันก็จะล้มเหลวเสมอ โฟลเดอร์นั้นมีอยู่เสมอบน Ubuntu หรือไม่?
หมอบลูกแมว

@CrouchingKitten ไดเรกทอรีใน/proc/1/อาจปลอดภัยกว่าเนื่องจาก init มีอยู่เสมอ แต่นั่นprocไม่ใช่ระบบไฟล์ปกติในกรณีที่สำคัญ
ilkkachu

ขอบคุณฉันให้ upvote แต่ยอมรับคำตอบอื่น ๆ เพราะเขาบอกว่ามันรับประกันว่า/proc/1/fdinfo/0ทำงานบน Ubuntus ทันสมัย
หมอบลูกแมว

-perm o-rwxเป็นเช่น-perm 0นั้นบิตทั้งหมดจะเริ่มต้นด้วย ! -perm -1ที่นี่คุณต้องการ
Stéphane Chazelas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.