Esiste un file che esiste sempre e che un utente "normale" non può installarlo?


14

Ne ho bisogno per un test unitario. C'è una funzione che esegue lstat sul percorso del file passato come parametro. Devo innescare il percorso del codice in cui illstat fallisce (perché la copertura del codice deve raggiungere il 90%)

Il test può essere eseguito solo con un singolo utente, quindi mi chiedevo se esiste sempre un file in Ubuntu, ma gli utenti normali non hanno accesso in lettura ad esso o alla sua cartella. (Quindi lstatfallirebbe se non eseguito come root.)

Un file inesistente non è una soluzione, perché esiste un percorso di codice separato per quello, che sto già attivando.

EDIT: la mancanza di accesso in lettura al solo file non è sufficiente. Con quello lstatpuò ancora essere eseguito. Sono stato in grado di attivarlo (sul mio computer locale, dove ho accesso root), creando una cartella in / root e un file al suo interno. E impostando l'autorizzazione 700 sulla cartella. Quindi sto cercando un file che si trova in una cartella accessibile solo da root.


6
IMHO/etc/shadow
Romeo Ninov,

3
Non puoi supporre l'esistenza di alcun file, perché il tuo programma potrebbe essere eseguito in un chroot o in uno spazio dei nomi separato. Se supponendo che / proc sia montato è OK e init non è niente di speciale, allora /proc/1/fd/0dovrebbe fare.
mosvy,

1
@mosvy Grazie che funziona sul mio computer locale. Quindi, lo proverò anche sul pool di controllo qualità e di gestione temporanea.
Gattino accovacciato

2
Perché leghi il tuo codice di test a un particolare stile del sistema operativo quando potresti semplicemente creare un file usa e getta e rimuovere il tuo accesso in lettura ad esso?
Kilian Foth,

4
Direi che non è davvero un test unitario una volta che inizia a seconda di un filesystem reale, piuttosto che deriso.
Toby Speight,

Risposte:


21

Sui moderni sistemi Linux, dovresti essere in grado di utilizzare /proc/1/fdinfo/0 (informazioni per il descrittore di file 1 (stdout) del processo di id 1 ( initnello spazio dei nomi pid root che dovrebbe essere eseguito come root)).

Puoi trovare un elenco con (come utente normale):

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

(rimuovere -type f se non si desidera limitare ai file normali).

/var/cache/ldconfig/aux-cacheè un altro potenziale candidato se devi solo considerare i sistemi Ubuntu. Dovrebbe funzionare sulla maggior parte dei sistemi GNU quando /var/cache/ldconfigviene creato read + write + ricercabile su root solo dal ldconfigcomando fornito con GNU libc.


1
Grazie! Se /proc/1/fdinfo/0funziona su Ubuntu 16.04 e 18.04, è più che sufficiente.
Gattino accovacciato

1
L'uso /proc/1/fdinfo/0non funziona necessariamente in un contenitore (ad esempio un contenitore Docker) e spesso i test unitari vengono eseguiti in tali contenitori in CI.
Philipp Wendler,

@PhilippWendler, ho già menzionato lo spazio dei nomi root pid . L'OP non sta chiedendo dei contenitori, ma dei file garantiti presenti nel layout del filesystem di un sistema Ubuntu. Dato che i contenitori potevano contenere qualsiasi layout di file e directory, quella domanda non poteva rispondere lì.
Stéphane Chazelas,

12

Looking at the lstat (2) pagina man puoi trarre ispirazione dai casi che potrebbero far fallire con errori diversi da ENOENT (il file non esiste.)

Il più ovvio è:

L' autorizzazione di ricerca EACCES è negata per una delle directory nel prefisso del percorso .

Quindi hai bisogno di una directory da cui non puoi cercare.

Sì, puoi cercarne uno già nel tuo sistema (forse /var/lib/privatese esiste?) Ma potresti anche crearne uno tu stesso, con l'equivalente di:

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

L'operazione lstat (2) fallirà con EACCES qui. (La rimozione di tutte le autorizzazioni dalla directory lo assicura. Forse non ne hai nemmeno bisogno e chmod -xrimuovere le autorizzazioni di esecuzione sarebbe sufficiente, poiché per accedere ai file in essa contenuti sono necessarie le autorizzazioni di esecuzione su una directory.)

C'è un altro modo creativo per far fallire lstat (2), guardando la sua pagina man:

ENOTDIR Un componente del prefisso percorso di percorso non è una directory.

Quindi, tentare di accedere a un file come quello /etc/passwd/nonexistentdovrebbe innescare questo errore, che è di nuovo diverso da ENOENT ("Nessun file o directory") e potrebbe soddisfare le tue esigenze.

Un altro è:

Il percorso ENAMETOOLONG è troppo lungo.

Ma potresti aver bisogno di un nome davvero lungo per questo (credo che 4.096 byte sia il limite tipico, ma il tuo sistema / filesystem potrebbe averne uno più lungo).

Infine, è difficile dire se qualcuno di questi sarà effettivamente utile per te. Dici di voler qualcosa che non inneschi lo scenario "il file non esiste". Sebbene in genere ciò significhi un errore ENOENT, in pratica molti controlli di livello superiore interpreteranno semplicemente qualsiasi errore di lstat (2) come "non esiste". Ad esempio test -eo l'equivalente [ -e ...]della shell potrebbe semplicemente interpretare tutto quanto sopra come "non esiste", soprattutto perché non ha un buon modo per restituire un messaggio di errore diverso e non restituire un errore implicherebbe che il file esiste, che certamente non è il caso.


@StephaneChazelas Ottimo punto! Aggiornato.
filbranden,

6

Puoi findfarlo tu stesso.

Utilizzo /etc: la directory dei file di configurazione come punto di partenza:

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

Sul mio sistema, questo non restituisce nulla.

Puoi essere un gruppo meno restrittivo e consentire root(solo l'utente rootdovrebbe essere un membro del gruppo root) e cercare un'autorizzazione per 440:

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

Sul mio sistema questo ritorna:

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

Modificare:

In base alla modifica, stai cercando una directory che non disponga dell'autorizzazione sufficiente per l'utente che invoca per impedire l'elenco delle directory:

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

qui sto cercando directory ( -type d) che non hanno i perm bit di lettura-scrittura-esecuzione per gli altri ( o-rwx) ed è di proprietà di root:root.

Tecnicamente, solo l'assenza del xbit execute ( ) impedirebbe un elenco di directory ( lstat(2)) sulla directory.

Nell'output ho trovato /run/systemd/inaccessible/sul mio sistema basato su init Systemd.

Per quanto riguarda i file in /proc, /sys, /dev:

  • Questi filesystem sono FS virtuali, cioè risiedono in memoria, non su disco

  • Se si prevede di fare affidamento /proc, utilizzare /proc/1/cioè fare affidamento su qualcosa ai sensi del PID 1, non tutti i PID successivi avranno affidabilità / coerenza poiché i PID (processi) successivi non sono garantiti.


Grazie, penso che la mia domanda sia sbagliata. Riesco ancora a lstat file senza accesso in lettura ad essi. Forse l'accesso alla cartella deve essere limitato? (Ho modificato il titolo)
Gattino accovacciato

Grazie. Con find / -type d -perm 0400 -user rootho trovato la directory /proc/20/map_files/, se mi riferisco a un nome di file inventato all'interno di quella cartella, come /proc/20/map_files/asdasd, allora fallisce sempre. Quella cartella esiste sempre su Ubuntu?
Gattino accovacciato

@CrouchingKitten, le directory in /proc/1/potrebbero essere più sicure, poiché init esiste sempre. Ma questo procnon è un normale filesystem, nel caso sia importante.
ilkkachu,

Grazie ho dato un voto, ma ho accettato l'altra risposta, perché ha detto che è garantito che /proc/1/fdinfo/0funziona su Ubuntus moderno.
Gattino accovacciato

-perm o-rwxè come -perm 0, i bit sono tutti fuori per cominciare. Ecco, vorresti ! -perm -1.
Stéphane Chazelas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.