Her zaman var olan bir dosya var mı ve 'normal' kullanıcı bunu atamıyor mu?


14

Birim testi için buna ihtiyacım var. Parametre olarak iletilen dosya yolunda lstat yapan bir işlev var . Ben lstatbaşarısız olduğu kod yolunu tetiklemek zorunda (çünkü kod kapsamı% 90 ulaşmak zorunda)

Test yalnızca tek bir kullanıcı altında çalışabilir, bu nedenle Ubuntu'da her zaman var olan bir dosya olup olmadığını merak ediyordum, ancak normal kullanıcıların ona veya klasörüne okuma erişimi yok. ( lstatKök olarak yürütülmedikçe başarısız olur.)

Varolmayan bir dosya bir çözüm değildir, çünkü bunun için zaten tetiklediğim ayrı bir kod yolu vardır.

DÜZENLEME: Yalnızca dosyaya okuma erişiminin olmaması yeterli değildir. Bununla lstathala yürütülebilir. / Root içinde bir klasör ve içinde bir dosya oluşturarak (root erişimi olan yerel makinemde) tetikleyebildim. Ve klasörde izin 700 ayarlanıyor. Bu yüzden sadece root tarafından erişilebilen bir klasördeki bir dosyayı arıyorum.


6
IMHO/etc/shadow
Romeo Ninov

3
Programınız bir chroot veya ayrı bir ad alanında çalışabileceğinden herhangi bir dosyanın var olduğunu varsayamazsınız. / Proc'un takılı olduğunu varsayarsak ve init özel bir şey değilse, /proc/1/fd/0yapmalısınız.
mosvy

1
@mosvy Yerel makinemde çalışan teşekkürler. Hmm o zaman ben de QA ve Staging havuzunda deneyeceğim.
Crouching Kitten

2
Neden bir tek kullanımlık dosya oluşturup kendi okuma erişiminizi kaldırabildiğinizde test kodunuzu belirli bir işletim sistemi lezzetine bağlıyorsunuz ?
Kilian Foth

4
Ben alay yerine, gerçek bir dosya sistemine bağlı olarak başladığında bir birim testi olmadığını iddia ediyorum .
Toby Speight

Yanıtlar:


21

Modern Linux sistemlerinde kullanabilmeniz gerekir /proc/1/fdinfo/0(id 1 işleminin dosya tanımlayıcısı 1 (stdout) için bilgi ( initolması gereken kök pid ad alanında root)).

(Normal kullanıcı olarak) ile bir liste bulabilirsiniz:

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

( -type fnormal dosyalarla kısıtlamak istemiyorsanız kaldırın ).

/var/cache/ldconfig/aux-cachesadece Ubuntu sistemlerini göz önünde bulundurmanız gerekiyorsa başka bir potansiyel adaydır. Sadece GNU libc ile birlikte gelen komutla /var/cache/ldconfigroot + olarak okunabilir olarak oluşturulduğu gibi çoğu GNU sisteminde çalışmalıdır ldconfig.


1
Teşekkürler! Eğer /proc/1/fdinfo/0yeterinden fazla var Ubuntu 16.04 ve 18.04 yönelik çalışmalara başlanmıştır.
Crouching Kitten

1
Kullanmak /proc/1/fdinfo/0bir kapta (örn. Bir Docker kapında) çalışmak zorunda değildir ve genellikle birim testleri CI'daki bu kaplarda gerçekleştirilir.
Philipp Wendler

@PhilippWendler, zaten kök pid ad alanından bahsetmiştim . OP, kapsayıcılar hakkında değil, bir Ubuntu sisteminin dosya sistemi düzeninde olması garanti edilen dosyalar hakkında sorular soruyor. Kapsayıcılar herhangi bir dosya ve dizin düzeni içerebileceğinden, bu soru burada yanıtlanamaz.
Stéphane Chazelas

12

Baktığımızda lstat (2) kılavuz sayfasında bunu ENOENT dışındaki hatalar ile başarısız hale getirebileceğini durumlarda ilgili ilhama alabilirsiniz (dosya yok.)

En bariz olanı:

EACCES Arama izni yolu öneki bölümündeki telefon için engellendi yolu .

Arama yapamayacağınız bir dizine ihtiyacınız var.

Evet, zaten sisteminizde olanı arayabilirsiniz (belki de /var/lib/privatevarsa?) Ama aynı şeyi kendiniz de yaratabilirsiniz:

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

Lstat (2) işlemi burada EACCES ile başarısız olacaktır. (Dizindeki tüm izinlerin kaldırılması bunu sağlar. Belki de o kadar çok ihtiyacınız yoktur ve chmod -xyürütme izinlerini kaldırmanız yeterli olacaktır, çünkü bir dizindeki dosyalara erişmek için yürütme izinleri gerekir.)

Lstat (2) 'nin man sayfasına bakarak başarısız olmasının başka bir yaratıcı yolu daha var:

ENOTDIR yolu öneki bir bileşeni yolunun bir dizin değil.

Bu nedenle, bir dosyaya erişmeye çalışmak /etc/passwd/nonexistent, yine ENOENT'ten ("Böyle bir dosya veya dizin yok") farklı olan ve ihtiyaçlarınızı karşılayabilecek bu hatayı tetiklemelidir.

Bir diğeri:

ENAMETOOLONG yolu çok uzun.

Ancak bunun için gerçekten uzun bir isme ihtiyacınız olabilir (Sanırım 4.096 bayt tipik sınırdır, ancak sisteminizin / dosya sisteminizin daha uzun bir adı olabilir.)

Son olarak, bunlardan herhangi birinin sizin için gerçekten yararlı olup olmayacağını söylemek zor . "Dosya mevcut değil" senaryosunu tetiklemeyen bir şey istediğinizi söylüyorsunuz. Tipik olarak bu bir ENOENT hatası anlamına gelse de, pratikte birçok üst düzey kontrol lstat (2) 'den gelen hataları "yok" olarak yorumlayacaktır. Örneğin test -eveya [ -e ...]kabuğun eşdeğeri , yukarıdakilerin tümünü yalnızca "yok" olarak yorumlayabilir, özellikle de farklı bir hata iletisi döndürmek için iyi bir yolu olmadığından ve bir hata döndürmemek dosyanın var olduğu anlamına gelir, bu kesinlikle böyle değil.


@StephaneChazelas Harika bir nokta! Güncellenmiş.
filbranden

6

Kendiniz yapabilirsiniz find.

Kullanılması /etc- Bir başlangıç noktası olarak konfigürasyon dosyaları dizinine:

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

Sistemimde, bu hiçbir şey döndürmez.

Daha az kısıtlayıcı olabilir ve gruba izin verebilirsiniz root(yalnızca kullanıcının rootgrubun üyesi olması gerekir root) ve aşağıdaki izinlere dikkat edin 440:

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

Sistemimde bu döndürür:

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

Düzenle:

Düzenlemenize bağlı olarak, çağıran kullanıcının dizin listelemesini engellemesi için yeterli izne sahip olmayan bir dizin arıyorsunuz:

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

burada -type ddiğerleri için okuma-yazma-yürütme izin biti eksik dizinleri ( ) arıyorum ( o-rwx) ve ait root:root.

Teknik olarak, sadece execute ( x) bitinin olmaması dizin lstat(2)üzerindeki bir dizin listesini ( ) önler .

Çıktıda /run/systemd/inaccessible/Systemd init tabanlı sistemimi buldum .

Dosyaları ile ilgili olarak /proc, /sys, /dev:

  • Bu dosya sistemleri sanal FS'dir, yani diskte değil, bellekte bulunurlar

  • Eğer güvenmeyi planlıyorsanız /proc, /proc/1/yani PID 1 altında bir şeye güvenin, daha sonraki PID'lerin (süreçlerin) varolduğu garanti edilmediğinden güvenilirlik / tutarlılığa sahip olmak için daha sonraki PID'lere güvenmeyin.


Teşekkürler, sanırım sorum yanlış. Ben hala onlara okuma erişimi olmadan lstat dosyaları yapabilirsiniz. Belki klasöre erişim sınırlandırılmalıdır? (Başlığı değiştirdim)
Crouching Kitten

Teşekkürler. İle find / -type d -perm 0400 -user rootben dizin bulduk /proc/20/map_files/ben bu klasörün içinde uydurma bir dosya adına başvurmak, eğer böyle /proc/20/map_files/asdasd, o zaman her zaman başarısız olur. Bu klasör her zaman Ubuntu'da var mı?
Crouching Kitten

@CrouchingKitten, /proc/1/init her zaman var olduğu için dizinler daha güvenli olabilir. Ancak bu proc, önemli olması durumunda normal bir dosya sistemi değildir.
ilkkachu

Teşekkürler bir oy verdim, ancak diğer cevabı kabul ettim, çünkü /proc/1/fdinfo/0modern Ubuntus üzerinde çalışacağının garanti edildiğini söyledi.
Crouching Kitten

-perm o-rwxgibidir -perm 0, bitler başlamak için kapalıdır. Burada istersiniz ! -perm -1.
Stéphane Chazelas
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.