2015-07-25 3 views
14

Podczas pracy nad projektem, który brzmi od /dev/urandom w celu wygenerowania losowych bajtów, zasugerowano, żebym sprawdził, aby upewnić się, że /dev/urandom to urządzenie, a nie tylko plik.Jak zagwarantować określony plik to urządzenie na BSD/Linux z PHP?

Najprostszym sposobem wydaje się być coś takiego:

/** 
* 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; 
} 

Moje pytanie jest dwojaki:

  1. Jest to najlepszy sposób, aby sprawdzić, że ten plik to urządzenie?
  2. Czy istnieją okoliczności, w których ta kontrola może się nie udać?

Ważne: Rozwiązanie muszę musi być w PHP bez zależności od dowolnego PECL rozszerzeń lub niestandardowego kodu C. Projekt ma postać a pure PHP 5 polyfill of PHP 7's random_bytes() and random_int() functions i ma być instalowany w dowolnych projektach PHP 5 autorstwa Composer.

+0

[Widziałeś to?] (Http://insanecoding.blogspot.com/2014/05/a-good-idea-with-bad-usage-devurandom.html) –

+0

Moje obecne nieoficjalne stanowisko brzmi: "TOCTOU problemy i ataki polegające na wyczerpaniu deskryptorów plików są poza zakresem.Jeśli twój system plików jest pwned, to nic nie może zrobić twoja aplikacja internetowa PHP, żeby cię uratować. " –

Odpowiedz

4

cóż, możesz użyć typu filet().

jeśli zrobić szybki ll na urandom, można zobaczyć:

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

że 'c' w beginnng oznacza, że ​​jest to "znak" filetype. można sprawdzić wszystkie różnych typów plików tutaj:

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

oznacza to, że po uruchomieniu

filetype("/dev/urandom"); 

dostaniesz "char" back, czyli znak filetype. ten powinien załatwić sprawę.

+1

"powinieneś poświęcić czas na zbadanie openssl_random_pseudo_bytes()." [To nie jest pierwszy wybór, który polecam każdemu] (https://github.com/paragonie/random_compat/blob/master/ERRATA.md). Omawiany projekt jest funkcją polyfill dla funkcji 'random_bytes()' i 'random_int()' w PHP 7. –

2

Aktualizacja

Mój oryginalny rozwiązanie okazało się być po prostu re-implementacja filetype($filepath) === 'char', więc filetype() wydaje się być jedyną rzeczą, której potrzebują.


podstawie odpowiedzi @ FRYMASTER za ...

Spojrzałem na jak stat() funkcja PHP działa, szuka "char" i stwierdził this.

połączeniu z stat (2) Podręcznik dla obu Linux i FreeBSD, jak również comment on PHP's manual for stat(), wpadłem na następujący:

 
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)); 
} 

działa na moim systemie Linux.

Update (do odpowiedzi na pytanie drugie)

Tak, stat($file)['rdev'] !== 0 może zawieść. Z tego, co znalazłem, może zwrócić -1, jeśli nie jest obsługiwany przez system operacyjny, a nawet wartość dodatnia może wskazywać na inny typ urządzenia.Jego wartości wydają się również zależne od systemu operacyjnego.

+0

Wygląda na to, że libsodum robi coś bardzo podobnego: https://github.com/jedisct1/libsodium/blob/024b74c84995e68c804868b1189d75f571794ad7/src/libsodium/randombytes/sysrandom/randombytes_sysrandom.c#L118 –

+2

I okazało się, że to jest 'filetype () 'zwraca" char ". :) Właśnie zaktualizowałem odpowiedź ... która jest teraz bardzo podobna do tego, co powiedział @frymaster. – Narf

+1

Nauczyłem się z tego rzeczy! Dziękuję Ci! – frymaster

Powiązane problemy