<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=iso-8859-1"><meta name=Generator content="Microsoft Word 14 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri","sans-serif";
        mso-fareast-language:EN-US;}
h1
        {mso-style-priority:9;
        mso-style-link:"Überschrift 1 Zchn";
        mso-margin-top-alt:auto;
        margin-right:0cm;
        mso-margin-bottom-alt:auto;
        margin-left:0cm;
        font-size:24.0pt;
        font-family:"Times New Roman","serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
pre
        {mso-style-priority:99;
        mso-style-link:"HTML Vorformatiert Zchn";
        margin:0cm;
        margin-bottom:.0001pt;
        font-size:10.0pt;
        font-family:"Courier New";}
span.E-MailFormatvorlage17
        {mso-style-type:personal-compose;
        font-family:"Calibri","sans-serif";
        color:windowtext;}
span.berschrift1Zchn
        {mso-style-name:"Überschrift 1 Zchn";
        mso-style-priority:9;
        mso-style-link:"Überschrift 1";
        font-family:"Times New Roman","serif";
        mso-fareast-language:DE;
        font-weight:bold;}
span.HTMLVorformatiertZchn
        {mso-style-name:"HTML Vorformatiert Zchn";
        mso-style-priority:99;
        mso-style-link:"HTML Vorformatiert";
        font-family:"Courier New";
        mso-fareast-language:DE;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri","sans-serif";
        mso-fareast-language:EN-US;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:70.85pt 70.85pt 2.0cm 70.85pt;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body lang=DE link=blue vlink=purple><div class=WordSection1><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><span lang=EN-US>Luca Bruno writes:<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:10.0pt;font-family:"Courier New";mso-fareast-language:DE'><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:10.0pt;font-family:"Courier New";mso-fareast-language:DE'>>Hi,<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:10.0pt;font-family:"Courier New";mso-fareast-language:DE'>>I'm not sure if it has been already discussed here, but I see that<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:10.0pt;font-family:"Courier New";mso-fareast-language:DE'>>after the latest Valgrind related problem, not the whole patch has been<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='font-size:10.0pt;font-family:"Courier New";mso-fareast-language:DE'>>dropped [0].<o:p></o:p></span></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Hi,<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><span lang=EN-US>i’m curious about that, too. I looked into the issue on a debian system<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>me@debian-vm: ~$ uname –a<sup><o:p></o:p></sup></span></p><p class=MsoNormal><span lang=EN-US>Linux debian-vm 3.2.0-4-amd64 #1 SMP Debian 3.2.46-1 x86_64 GNU/Linux<sup><o:p></o:p></sup></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>both with the stock openssl and with a fresh build of the library, sources obtained using <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>me@debian-vm:~$ sudo apt-get -b source openssl<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>Eric Wong’s proof-of-concept mentioned by Martin Boßlet on his blog [1] consists of a parent process that calls RAND_bytes once and then starts forking child processes until the system begins to recycle pids. The first child prints its pid and 4 bytes from the rnd stream, and a while later the next child that gets the same pid does the same. The program then exits. With Debian’s libssl the output is:<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>me@debian-vm:~$ gcc –o random random.c -lssl<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>me@debian-vm:~$ ./random<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>pid=4904 \x12\x78\x03\x3b<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>pid=4904 \x12\x78\x03\x3b<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>So both children produce the same sequence of random numbers. Debian seems to be the only linux to do that, I tried it on a SLES 11p2 and on an OpenSuSE and got differing random number sequences. From SLES sources I can tell that they don’t apply anything like the valgrind.patch. When I rebuild the Debian openssl library without the valgrind.patch, I get <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>me@debian-vm:~$ ./random<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>pid=5419 \x81\xc7\x69\x6f<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>pid=5419 \x83\xa4\x39\x8c<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>as expected.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>Now I wasn’t around in 2008 when the problem first surfaced, so I don’t know exactly what the fix was, but from what I read on Slashdot and elsewhere, I think the issue was that MD_Update was flagged by valgrind, and commented out in two places, ssleay_rand_bytes and then again in ssleay_rand_add. Afaik the latter was what caused the fracas, so it was removed in 2008, and the code now carries a big red warning sign (md_rand.c:279):<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>                               /* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! </span>*/<o:p></o:p></p><p class=MsoNormal>                               MD_Update(&m,buf,j);<o:p></o:p></p><p class=MsoNormal>                               <span lang=EN-US>/* We know that line may cause programs such as<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                                  purify and valgrind to complain about use of<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                                  uninitialized data.  The problem is not, it's<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                                  with the caller.  Removing that line will make<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                                  sure you get really bad randomness and thereby<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                                  other problems such as very insecure keys. */<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>                               MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>The former, though, stayed in the code, slightly modified (#if 0 instead of a straight comment), and that is the valgrind.patch of today.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>Index: openssl-1.0.0c/crypto/rand/md_rand.c<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>===================================================================<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>--- openssl-1.0.0c.orig/crypto/rand/md_rand.c   2010-06-16 15:17:22.000000000 +0<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>200<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+++ openssl-1.0.0c/crypto/rand/md_rand.c        2010-12-12 17:02:50.000000000 +0<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>100<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>@@ -476,6 +476,7 @@<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> #ifndef PURIFY /* purify complains */<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+#if 0<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                /* The following line uses the supplied buffer as a small<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                 * source of entropy: since this buffer is often uninitialised<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                 * it may cause programs such as purify or valgrind to<o:p></o:p></span></p><p class=MsoNormal>@@ -485,6 +486,7 @@<o:p></o:p></p><p class=MsoNormal>                 */<o:p></o:p></p><p class=MsoNormal>                MD_Update(&m,buf,j);<o:p></o:p></p><p class=MsoNormal> <span lang=EN-US>#endif<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>+#endif<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US> <o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                k=(st_idx+MD_DIGEST_LENGTH/2)-st_num;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                if (k > 0)<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>Why is this a problem? Well, in Eric’s code, the parent calls RAND_bytes *<b>before</b>* the first fork, causing ssleay_rand_bytes to call RAND_poll (md_rand.c:392), thus initializing the RNG:<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>                if (!initialized)<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                               {<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                               RAND_poll();<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                               initialized = 1;<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>                               }<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>As a side effect, initialized=1 blocks RAND_poll from *<b>ever being called again</b>*. Now the parent forks, and the children call RAND_bytes again. Now ssleay_rand_bytes skips RAND_poll, updates the entropy pool with the PID, and then there is only one other chance for individual entropy, the MD_Update call that valgrind.patch just removed. Result: all children with the same PID get the same random numbers. If the parent hadn’t called ssleay_rand_bytes each child would call RAND_poll individually, and all would be well.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>My twocent is: Commenting out the MD_Update call in ssleay_rand_bytes is just as incorrect, the problem just shows up less often than the original bug, that’s it why took a while before someone stumbled upon it [2]. Valgrind.patch should be removed.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>Ernst-Udo Wallenborn<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US>[1] <a href="http://emboss.github.io/blog/2013/08/21/openssl-prng-is-not-really-fork-safe/">http://emboss.github.io/blog/2013/08/21/openssl-prng-is-not-really-fork-safe/</a><o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US>[2] <a href="https://bugs.ruby-lang.org/issues/4579">https://bugs.ruby-lang.org/issues/4579</a><o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p></div></body></html>