16

I strace'd a simple script using perl and bash.

$ strace perl -e 'echo "test";' 2>&1 | grep 'random'
open("/dev/urandom", O_RDONLY)          = 3
$ strace bash 'echo "test"' 2>&1 | grep 'random'
$

Why does perl need the pseudorandom number generator for such a trivial script? I would expect opening /dev/urandom only after the first use of random data.

Edit: I also tested python and ruby

$ strace python -c 'print "test"' 2>&1 | grep random
$
$ strace ruby -e 'print "test\n"' 2>&1 | grep random
open("/dev/urandom", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_CLOEXEC) = 3

Why do perl and ruby open it with different modes?

dimid
  • 7,285
  • 1
  • 46
  • 85
  • 1
    Perhaps for seeding its own PRNG? – Daniel Kamil Kozar Nov 17 '14 at 22:49
  • generating random numbers is not a simple matter. /dev/random gives access to "random" data from the machine, so perl uses it. How else are you going to get random input? What is your problem with the way it is done? Do you need "better" pseudo-random numbers? – bytepusher Nov 17 '14 at 22:53
  • I tried the same on my system. It reads just 4 bytes from `/dev/urandom` and then closes it. – Keith Thompson Nov 17 '14 at 22:53
  • @bytepusher: It reads from `/dev/urandom`, not `/dev/random` (which doesn't affect your point). I note that it does so even if you don't call `srand` or `rand`. – Keith Thompson Nov 17 '14 at 22:55
  • @bytepusher I would expect opening /dev/urandom only after the first use of random data – dimid Nov 17 '14 at 22:55
  • 2
    It'd be interesting to test this on 5.20 http://www.effectiveperlprogramming.com/2014/06/perl-5-20-uses-its-own-random-number-generator/ – hmatt1 Nov 17 '14 at 23:10
  • 2
    This might be related? https://github.com/Perl/perl5/blob/bb6a367ad5d39a6d163bda06f6788f8e7833b713/util.c#L4513 – hmatt1 Nov 17 '14 at 23:16
  • @chilemagic: Yes, there's a call to `urandom()` in the `Perl_seed` function. It opens `/dev/urandom` (if it exists) and reads 4 bytes from it. I haven't tracked down how the result is used (and I'm not planning to), but my guess is that it stores the value internally, to be used later when calling `srand` (which can be done implicitly on the first call to `rand`). Why do it unconditionally on startup? Why not. It's hardly going to be a performance bottleneck. – Keith Thompson Nov 17 '14 at 23:25
  • It appears to be platform-specific. I see your results on Ubuntu 14, but on OSX Yosemite there are no random calls using current ruby (2.15), perl (5.18.2), python (2.7.8). – joelparkerhenderson Nov 17 '14 at 23:44
  • It probably uses it for things like hash seed randomization. See http://perldoc.perl.org/perlsec.html#Algorithmic-Complexity-Attacks, for example. – chepner Nov 17 '14 at 23:47
  • @ Keith Thompson - sorry, I misread your question. It may not have read that way, but I could and would have helped you out with that ;) – bytepusher Nov 18 '14 at 00:00

1 Answers1

18

Try searching for "Denial of Service via Algorithmic Complexity Attacks".

In brief, if a Perl script accepts outside input (from a file, network, etc) and stores that data in a hash, an attacker who can influence the data can exploit the hashing algorithm to deteriorate hashes (O(1) lookups) into linked lists (O(N) lookups). To defend against this type of attack, certain parameters of the hashing algorithm are randomised at program start-up so that an attacker cannot construct a sequence of hash keys that will cause a problem.

This is obviously not specific to Perl. Any program which uses a hashing algorithm is potentially vulnerable to this type of attack.

ikegami
  • 367,544
  • 15
  • 269
  • 518
Grant McLean
  • 6,898
  • 1
  • 21
  • 37
  • 5
    Also worth noting that the reason this is done at startup, instead of the first time you use a hash in perl, is that hashes are used internally - for example in the symbol table. – harmic Nov 18 '14 at 03:42