Ticket #9407: uuid_valgrind.patch

File uuid_valgrind.patch, 3.3 KB (added by Antony Polukhin, 9 years ago)
  • .

     
    3838#if defined(_MSC_VER)
    3939#pragma warning(push) // Save warning settings.
    4040#pragma warning(disable : 4996) // Disable deprecated std::fopen
     41#include <Windows.h> // for CryptAcquireContextA, CryptGenRandom, CryptReleaseContext
    4142#endif
    4243
    4344#ifdef BOOST_NO_STDC_NAMESPACE
     
    7879    seed_rng()
    7980        : rd_index_(5)
    8081        , random_(std::fopen( "/dev/urandom", "rb" ))
    81     {}
     82    {
     83        std::memset(rd_, 0, sizeof(rd_));
     84    }
    8285   
    8386    ~seed_rng()
    8487    {
     
    109112    }
    110113
    111114private:
     115    BOOST_STATIC_CONSTANT(std::size_t, internal_state_size = 5);
    112116    inline void ignore_size(size_t) {}
    113117
    114118    static unsigned int * sha1_random_digest_state_()
    115119    {
    116         static unsigned int state[ 5 ];
     120        static unsigned int state[ internal_state_size ];
    117121        return state;
    118122    }
    119123
     
    121125    {
    122126        boost::uuids::detail::sha1 sha;
    123127
    124         unsigned int * ps = sha1_random_digest_state_();
    125128
    126         unsigned int state[ 5 ];
    127         std::memcpy( state, ps, sizeof( state ) ); // harmless data race
     129        // intentionally left uninitialized
     130        unsigned char state[ 20 ];
     131        {
     132#if defined(BOOST_WINDOWS)
     133            HCRYPTPROV   hCryptProv;
     134            if (CryptAcquireContextA(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
     135                CryptGenRandom(hCryptProv, sizeof(state), state);
     136            }
     137            CryptReleaseContext(hCryptProv, 0);
     138#endif
     139            if (random_)
     140            {
     141                ignore_size(std::fread( state, 1, sizeof(state), random_ ));
     142            }
    128143
    129         sha.process_bytes( (unsigned char const*)state, sizeof( state ) );
     144            // using an uninitialized buffer[] if fopen or CryptGenRandom fails
     145            // intentional, we rely on its contents being random
     146            sha.process_bytes( state, sizeof( state ) );
     147        }
     148
     149        unsigned int * ps = sha1_random_digest_state_();
     150        sha.process_bytes( ps, internal_state_size * sizeof( unsigned int ) );
    130151        sha.process_bytes( (unsigned char const*)&ps, sizeof( ps ) );
    131152
    132153        {
     
    149170        }
    150171
    151172        {
    152             // intentionally left uninitialized
    153             unsigned char buffer[ 20 ];
    154 
    155             if(random_)
    156             {
    157                 ignore_size(std::fread( buffer, 1, 20, random_ ));
    158             }
    159 
    160             // using an uninitialized buffer[] if fopen fails
    161             // intentional, we rely on its contents being random
    162             sha.process_bytes( buffer, sizeof( buffer ) );
    163         }
    164 
    165         {
    166             // *p is intentionally left uninitialized
    167             unsigned int * p = new unsigned int;
    168 
    169             sha.process_bytes( (unsigned char const*)p, sizeof( *p ) );
     173            unsigned int * p = new unsigned int;           
    170174            sha.process_bytes( (unsigned char const*)&p, sizeof( p ) );
    171 
    172175            delete p;
     176 
     177            const seed_rng* this_ptr = this;
     178            sha.process_bytes( (unsigned char const*)&this_ptr, sizeof( this_ptr ) );
     179            sha.process_bytes( (unsigned char const*)&std::rand, sizeof( void(*)() ) );
    173180        }
    174181
    175182        sha.process_bytes( (unsigned char const*)rd_, sizeof( rd_ ) );