Hi David,

We do have a workaround already for our specific use case (the problem 
occurs at thread initialization time only, so serializing is a non-issue, 
and a static instance of a class-wrapped pthread mutex did the job), but I 
was thinking of a more general fix for the library in general. Is there any 
chance this will happen?

cheers,

Eric


On Wednesday, December 10, 2014 1:52:10 PM UTC+1, David Irvine wrote:

> There are a couple of cases where this is true, in our code base we have 
> used std::once_flags to get around the issue. In particular MSVC will 
> happily whiz by the statics even in c++11, it may be fixed in the upcoming 
> MSVC, but is an issue here. You can grab our code and diff it if you like 
> from here 
> https://github.com/dirvine/MaidSafe/tree/master/src/third_party_libs/cryptopp
>  
>
> This will be OK if you use c++11, otherwise it may be wise to look to 
> boost or hand craft a solution.
>
> On Wed, Dec 10, 2014 at 11:25 AM, Eric Cano <[email protected] 
> <javascript:>> wrote:
>
>> Dear Crypo++ mainteners,
>>
>> We experienced several cases of crashes in the constructor of the Base64 
>> class. The problem arises when constructing CryptoPP::Base64Decoder in 
>> parallel in 2 threads for the first time in a program. We identified the 
>> race condition:
>>
>> The constructor of Base64Decoder calls GetDecodingLookupArray:
>>
>> class Base64Decoder : public BaseN_Decoder
>> {
>> public:
>>         Base64Decoder(BufferedTransformation *attachment = NULL)
>>                 : BaseN_Decoder(GetDecodingLookupArray(), 6, attachment) 
>> {}
>>         void IsolatedInitialize(const NameValuePairs &parameters) {}
>> private:
>>         static const int * CRYPTOPP_API GetDecodingLookupArray();
>> };
>>
>> GetDecodingLookupArray initializes a static structure, and the 
>> initialization is protected by a racy mechanism:
>>
>> const int *Base64Decoder::GetDecodingLookupArray()
>> {
>>         static volatile bool s_initialized = false;
>>         static int s_array[256];
>>         if (!s_initialized)
>>         {
>>                 InitializeDecodingLookupArray(s_array, s_vec, 64, false);
>>                 s_initialized = true;
>>         }
>>         return s_array;
>> }
>>
>>
>> When thread 1 passes the if (!s_initialized) test, thread 2 has ample 
>> time to pass it as well and to concurrently initialize the array, before 
>> thread 1 reaches s_initialized = true;.
>> A solution would be to use a mutex, which is a multiplatform issue unless 
>> CryptoPP gets compiled in C++11 (the language now has built-in mutexes).
>>
>> Another solution would be to unconditionally initialize all those 
>> structures at library load time by using a singleton's constructor. 
>> Drawback is longer load time and memory use.
>>
>> Yet another way would be to just make those structures compile-time 
>> static arrays, pre-computed in the source. Drawback is bigger binary, and 
>> usage of external script to pre-cook the sources.
>>
>> There are are a few other suspect cases in the code:
>>
>> $ grep static -r c5/*   | grep -n bool  | grep -v \(
>> 15:c5/base32.cpp:       static volatile bool s_initialized = false;
>> 20:c5/base64.cpp:       static volatile bool s_initialized = false;
>> 68:c5/datatest.cpp:static bool s_thorough;
>> 161:c5/gcm.h:   static volatile bool s_reductionTableInitialized;
>> 186:c5/gost.h:          static volatile bool sTableCalculated;
>> 190:c5/hex.cpp: static volatile bool s_initialized = false;
>> 196:c5/hrtimer.cpp:     static bool getCurrentThreadImplemented = true;
>> 205:c5/idea.h:          static volatile bool tablesBuilt;
>> 338:c5/regtest.cpp:     static bool s_registered = false;
>> 342:c5/rijndael.cpp:static volatile bool s_TeFilled = false, s_TdFilled = 
>> false;
>>
>> Cheers,
>>
>> Eric Cano
>>
>>  -- 
>> -- 
>> You received this message because you are subscribed to the "Crypto++ 
>> Users" Google Group.
>> To unsubscribe, send an email to [email protected] 
>> <javascript:>.
>> More information about Crypto++ and this group is available at 
>> http://www.cryptopp.com.
>> --- 
>> You received this message because you are subscribed to the Google Groups 
>> "Crypto++ Users" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to [email protected] <javascript:>.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>
>
> -- 
>
> David Irvine
> twitter: @metaquestions
> blog:  http://metaquestions.me
>  

-- 
-- 
You received this message because you are subscribed to the "Crypto++ Users" 
Google Group.
To unsubscribe, send an email to [email protected].
More information about Crypto++ and this group is available at 
http://www.cryptopp.com.
--- 
You received this message because you are subscribed to the Google Groups 
"Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to