2015-07-25 3 views
14

Während der Arbeit an einem Projekt, das von /dev/urandom liest, um zufällige Bytes zu generieren, wurde vorgeschlagen, dass ich überprüfe, um sicherzustellen, dass /dev/urandom ein Gerät nicht nur eine Datei ist.Wie garantiert man eine bestimmte Datei ist ein Gerät unter BSD/Linux von PHP?

Die einfachste Art und Weise scheint so etwas wie zu sein:

/** 
* Is the given file a device? 
* 
* @param string|resource $file 
* @return boolean 
*/ 
function is_device($file) 
{ 
    if (is_resource($file)) { 
     $stat = fstat($file);    
    } elseif (is_readable($file) && !is_link($file)) { 
     $stat = stat($file); 
    } else { 
     return false; 
    } 
    return $stat['rdev'] !== 0; 
} 

Meine Frage ist zweifach: dass diese Datei ein Gerät überprüfen

  1. Ist dies der beste Weg?
  2. Gibt es Umstände, unter denen diese $stat['rdev'] !== 0 Prüfung fehlschlagen kann?

Wichtige: Die Lösung, die ich ohne Abhängigkeit von jedem PECL-Erweiterungen oder benutzerdefinierte C-Code in PHP sein müssen müssen. Das Projekt ist a pure PHP 5 polyfill of PHP 7's random_bytes() and random_int() functions und soll in jedem anderen PHP 5-Projekt von Composer installiert werden können.

+0

[Haben Sie gesehen?] (Http://insanecoding.blogspot.com/2014/05/a-good-idea-with-bad-usage-devurandom.html) –

+0

Meine derzeitige inoffizielle Haltung ist, "TOCTOU Probleme und Erschöpfungsattacken bei Dateideskriptoren liegen außerhalb des Geltungsbereichs. Wenn Ihr Dateisystem komprimiert ist, kann Ihre PHP-Webanwendung nichts mehr tun, um Sie zu retten. " –

Antwort

4

Nun, Sie können Dateityp() verwenden.

wenn Sie einen schnellen ll auf urandom tun, werden Sie sehen:

ll /dev/urandom 
crw-rw-rw- 1 root root 1, 9 Jul 26 17:38 /dev/urandom 

dass ‚c‘ an der beginnng bedeutet es ein „Zeichen“ Dateityp ist. Sie können hier alle verschiedenen Dateitypen finden Sie unter:

https://en.wikipedia.org/wiki/Unix_file_types

bedeutet dies, dass, wenn Sie

filetype("/dev/urandom"); 

laufen Sie „char“ zurück, was bedeutet, Charakter Datei des Typs erhalten. dass sollte den Trick tun.

+1

"Sie sollten sich die Zeit nehmen, um openssl_random_pseudo_bytes() zu untersuchen." [Das ist nicht die erste Wahl, die ich jedem empfehlen würde] (https://github.com/paragonie/random_compat/blob/master/ERRATA.md). Das fragliche Projekt ist ein Polyfill für die 'random_bytes()' - und 'random_int()' -Funktionen von PHP 7. –

2

aktualisieren

Meine ursprüngliche Lösung ist gerade mal eine Neuimplementierung von filetype($filepath) === 'char' erwiesen, so filetype() das einzige, was zu sein scheint, die Sie benötigen.


Basierend auf Antwort des @ Frymaster ...

Ich sah, wie stat() Funktion arbeitet PHP, für "char" suchen und gefunden this.

mit der Stat-Kombi (2) sowohl manuell für Linux und FreeBSD sowie ein comment on PHP's manual for stat(), kam ich mit der Follow-up:

 
function is_device($filepath) 
{ 
     if (! file_exists($filepath) OR (stripos(PHP_OS, 'Linux') === false && stripos(PHP_OS, 'BSD') === false)) 
     { 
       return false; 
     } 

     $mode = stat($filepath)['mode']; 
     return (020000 === ($mode & 0170000)); 
} 

Arbeiten auf meinem Linux-System.

-Update fehlschlagen

Ja, stat($file)['rdev'] !== 0 kann (die zweite Frage zu beantworten). Von dem, was ich gefunden habe, kann es -1 zurückgeben, wenn es vom Betriebssystem nicht unterstützt wird, während sogar ein positiver Wert auf einen anderen Gerätetyp zeigen kann.Seine Werte scheinen auch OS-abhängig zu sein.

+0

Es scheint, dass libsodum etwas sehr ähnliches tut: https://github.com/jedisct1/libsodium/blob/024b74c84995e68c804868b1189d75f571794ad7/src/libsodium/randombytes/sysrandom/randombytes_sysrandom.c#L118 –

+2

Und das stellte sich heraus, was Dateityp () 'kehrt zu 'char' zurück. :) Habe gerade die Antwort aktualisiert ... was jetzt sehr ähnlich ist wie das, was @frymaster gesagt hat. – Narf

+1

Ich lernte Dinge daraus! Danke! – frymaster

Verwandte Themen