On 17.05.2016 08:28, Vincent Veyron wrote:
On Mon, 16 May 2016 22:45:14 +0000
"Bruce  Johnson" <john...@pharmacy.arizona.edu> wrote:


I don’t think it would be likely for Vincent to ever see this once, let alone 
have it rise to the issue of a problem if it were strictly about non-randomness 
of the rand() function.


Indeed : I also use the function to generate cookies; the strings are stored in a 
database table with a primary key on the token ; running 'ab -c 4 -n 4000 
"http://my/url/here";' 3 times yields 12 000 unique keys on a functional server.

The machine where the error showed up can't get two different strings in a row. 
It's a backup server, so I'm the only one using it for test purposes, which is 
why I did not notice the error before; it may have been present for a long time.

Below is what is installed on each machine, the first one (arsene) being the 
faulty one; it is a rather old Dell desktop, the others are dedicated servers 
in datacenters, such as kimsufi.com, online.net. Everything is on bare metal, 
and incidentally not as uniform as I thought :-(
reload-perl is installed but disabled in apache2.conf

perl -v on the faulty machine (arsene) :
This is perl 5, version 20, subversion 2 (v5.20.2) built for 
i586-linux-gnu-thread-multi-64int
perl -v on the good ones :
This is perl 5, version 20, subversion 2 (v5.20.2) built for 
x86_64-linux-gnu-thread-multi


arsene (cpuinfo : Intel(R) Core(TM)2 Duo CPU     E7500  @ 2.93GHz)
ii  apache2                          2.4.10-10+deb8u4       i386         Apache 
HTTP Server
ii  apache2-bin                      2.4.10-10+deb8u4       i386         Apache 
HTTP Server (modules and other binary files)
ii  apache2-data                     2.4.10-10+deb8u4       all          Apache 
HTTP Server (common files)
ii  apache2-mpm-prefork              2.4.10-10+deb8u4       i386         
transitional prefork MPM package for apache2
ii  apache2-utils                    2.4.10-10+deb8u4       i386         Apache 
HTTP Server (utility programs for web servers)
ii  apache2.2-common                 2.4.10-10+deb8u4       i386         
Transitional package for apache2
ii  libapache2-mod-apreq2            2.13-4+b1              i386         
generic Apache request library - Apache module
ii  libapache2-mod-perl2             2.0.9~1624218-2+deb8u1 i386         
Integration of perl with the Apache2 web server
ii  libapache2-reload-perl           0.12-3                 all          module 
for reloading Perl modules when changed on disk
ii  libapache2-request-perl          2.13-4+b1              i386         
generic Apache request library - Perl modules

kimsufi (cpuinfo : Intel(R) Atom(TM) CPU N2800   @ 1.86GHz)
ii  apache2                          2.4.10-10+deb8u4       amd64        Apache 
HTTP Server
ii  apache2-bin                      2.4.10-10+deb8u4       amd64        Apache 
HTTP Server (modules and other binary files)
ii  apache2-data                     2.4.10-10+deb8u4       all          Apache 
HTTP Server (common files)
ii  apache2-mpm-prefork              2.4.10-10+deb8u4       amd64        
transitional prefork MPM package for apache2
ii  apache2-utils                    2.4.10-10+deb8u4       amd64        Apache 
HTTP Server (utility programs for web servers)
ii  apache2.2-common                 2.4.10-10+deb8u4       amd64        
Transitional package for apache2
ii  libapache2-mod-apreq2            2.13-4+b1              amd64        
generic Apache request library - Apache module
ii  libapache2-mod-perl2             2.0.9~1624218-2+deb8u1 amd64        
Integration of perl with the Apache2 web server
ii  libapache2-reload-perl           0.12-3                 all          module 
for reloading Perl modules when changed on disk
ii  libapache2-request-perl          2.13-4+b1              amd64        
generic Apache request library - Perl modules

online (cpuinfo : VIA Nano processor U2250 (1.6GHz Capable))
ii  apache2                   2.4.10-10+deb8u4       amd64        Apache HTTP 
Server
ii  apache2-bin               2.4.10-10+deb8u4       amd64        Apache HTTP 
Server (modules and other binary files)
ii  apache2-data              2.4.10-10+deb8u4       all          Apache HTTP 
Server (common files)
ii  apache2-mpm-prefork       2.4.10-10+deb8u4       amd64        transitional 
prefork MPM package for apache2
ii  apache2-utils             2.4.10-10+deb8u4       amd64        Apache HTTP 
Server (utility programs for web servers)
ii  libapache2-mod-apreq2     2.13-4+b1              amd64        generic 
Apache request library - Apache module
ii  libapache2-mod-perl2      2.0.9~1624218-2+deb8u1 amd64        Integration 
of perl with the Apache2 web server
ii  libapache2-request-perl   2.13-4+b1              amd64        generic 
Apache request library - Perl modules

ovh (cpuinfo : Intel(R) Celeron(R) CPU          220  @ 1.20GHz)
ii  apache2                   2.4.10-10+deb8u4       amd64        Apache HTTP 
Server
ii  apache2-bin               2.4.10-10+deb8u4       amd64        Apache HTTP 
Server (modules and other binary files)
ii  apache2-data              2.4.10-10+deb8u4       all          Apache HTTP 
Server (common files)
ii  apache2-utils             2.4.10-10+deb8u4       amd64        Apache HTTP 
Server (utility programs for web servers)
ii  libapache2-mod-apreq2     2.13-4+b1              amd64        generic 
Apache request library - Apache module
ii  libapache2-mod-perl2      2.0.9~1624218-2+deb8u1 amd64        Integration 
of perl with the Apache2 web server
ii  libapache2-reload-perl    0.12-3                 all          module for 
reloading Perl modules when changed on disk
ii  libapache2-request-perl   2.13-4+b1              amd64        generic 
Apache request library - Perl modules


I don't see above any signifiant difference in configuration between the servers, apart from the fact that the "faulty" server runs a 64-bit version of perl.

But I still wonder if this is the issue :

http://perldoc.perl.org/functions/srand.html
says :

"If srand() is not called explicitly, it is called implicitly without a parameter at the first use of the rand operator. However, there are a few situations where programs are likely to want to call srand. One is for generating predictable results, generally for testing or debugging. There, you use srand($seed), with the same $seed each time. Another case is that you may want to call srand() after a fork() to avoid child processes sharing the same seed value as the parent (and consequently each other)."

This would tend to imply that the "real" seed used initially by srand() (such as when it is called implicitly at the first call to rand()), is something inside the perl interpreter itself. In a pre-fork configuration, the main Apache process starts first, and loads a perl interpreter. Then this main Apache process is forked into nn Apache children processes. Which means that the initial copies of the perl interpreter, in each child, are also identical. The main Apache process never runs any request (it just passes them to a child, which does run the request), so its copy of the perl interpreter remains "pristine", as it was before the first fork. If at some point there are not enough children alive, the main process forks again to create a new child.
So basically all children, present and future, start with the same perl.
And thus with the same whatever-it-is that is the seed of the first srand() (implicitly called by the first rand()). So, unless they all do explicitly call srand() once with each a different seed, each child does generate exactly the same sequence of responses to successive rand() calls. In other words, on any given machine, the Nth un-keyed request hitting one particular Apache child, will generate the same key as the Nth un-keyed request hitting any other child (assuming rand() is not used anywhere else).
(By "un-keyed request", I mean one which triggers the key-generating 
instruction).
(and N including perhaps also the requests which trigger similar calls to rand to generate a cookie, if they call rand() the same number of times (32)).

Except that..
The machine where the problem shows up so quickly, is running a 64-bit perl, while the others are running 32-bit perls.

Now I also found this :
  http://rabexc.org/posts/randomizing-should-be-easy-right-oh

I am not sure that I really understand this all the way down, but would this not be a suspect in a case where the behaviour seems different between one 64-bit machine, and a bunch of 32-bit ones ?

This being said, it still looks to me as if the current code is flawed on *all* machines, and *will* repeat keys quite often. It just depends again on the exact sequence of requests hitting a specific Apache, and the other parameters I mentioned before. I still believe that the fact that it does not *seem* to happen, is just due to the inherent randomness of these other factors on the production machines.

Reply via email to