Folks:

We're trying to get pycryptopp to link against the system-provided libcryptopp.so on Debian and Fedora, as well as to not crash in mysterious ways some of the time. Here is the most recent note that I sent about this issue to the cryptopp-users mailing list:

http://groups.google.com/group/cryptopp-users/browse_thread/thread/ eb815f228db50380

Regards,

Zooko


Begin forwarded message:

From: Zooko Wilcox-O'Hearn <[email protected]>
Date: May 23, 2009 21:03:29 PM MDT
To: Zooko Wilcox-O'Hearn <[email protected]>
Cc: Wei Dai <[email protected]>, "Crypto++ Users" <cryptopp- [email protected]>
Subject: Re: that problem with comparing types across DLLs

Dear Wei Dai et al.:

It is as I feared -- using the RTLD_GLOBAL flag for dlopen solves the problem in question but leads to other problems.

My project produces four different .so files, each of which is built by including some of the .o files from Crypto++. If I set RTLD_GLOBAL then if more than one of these .so files is loaded into the same process, the second and later ones to be loaded have something messed up which quickly leads to a crash. Attached is the output of valgrind showing the details of one such crash. (This is all 100% reproducible using the pycryptopp unit test suite.)

What I really want is for there to exist some way in C++ that you can express the following alternatives:

1. For a given symbol, for example the type_info of an exception class, then any code which #included that symbol, when loaded at run-time, will get the same unique value so that throw and catch and name-based arguments will work between any pair of DSOs.

2. For other symbols, any code which #includes that code will get its own separate address (symbol value) at run-time so that changes made to the value stored in that address (symbol) by one DSO won't affect other DSOs.

I *think* that this is the intent of __declspec(dllexport) and its brethren.

However, not understanding how to make this work with g++, if it is even possible, or if it is even a coherent thing to want, my next step is to declare that you can't have more than one DSO which uses Crypto++ code in your process, so I'll refactor my pycryptopp library to build all of the four features (AES, SHA256, RSA, and ECDSA), as well as upcoming features (XSalsa20, Tiger) in one DSO which is linked by including .o files from Crypto++. This will work as long as nobody tries to use my DSO along with another DSO which also uses Crypto++.

Oh, there's another alternative open to me -- make the pycryptopp build system build a custom Crypto++ DSO (or maybe just the standard Crypto++ DSO as specified by the Crypto++ GNUmakefile), and then build four DSOs each of which dynamically links to that shared DSO and continue to use RTLD_GLOBAL. This is actually already shown to work for our current unit test suite, but I don't trust it because I don't understand why RTLD_GLOBAL causes these crashes in other situations.

Regards,

Zooko
test (pycryptopp.test.test_ecdsa.SignAndVerify) ... ==26182== Jump to the 
invalid address stated on the next line
==26182==    at 0x0: ???
==26182==    by 0x9D1B722: CryptoPP::AsymmetricMultiply(unsigned long long*, 
unsigned long long*, unsigned long long const*, unsigned long, unsigned long 
long const*, unsigned long) (integer.cpp:2199)
==26182==    by 0x9D1C5C1: CryptoPP::Divide(unsigned long long*, unsigned long 
long*, unsigned long long*, unsigned long long const*, unsigned long, unsigned 
long long const*, unsigned long) (integer.cpp:2538)
==26182==    by 0x9D1D8EB: CryptoPP::PositiveDivide(CryptoPP::Integer&, 
CryptoPP::Integer&, CryptoPP::Integer const&, CryptoPP::Integer const&) 
(integer.cpp:3741)
==26182==    by 0x9D1D932: CryptoPP::Integer::Divide(CryptoPP::Integer&, 
CryptoPP::Integer&, CryptoPP::Integer const&, CryptoPP::Integer const&) 
(integer.cpp:3746)
==26182==    by 0x9D1DA00: CryptoPP::Integer::Modulo(CryptoPP::Integer const&) 
const (integer.cpp:3800)
==26182==    by 0x9C58C30: 
CryptoPP::MontgomeryRepresentation::ConvertIn(CryptoPP::Integer const&) const 
(modarith.h:132)
==26182==    by 0xA574DC6: CryptoPP::ECP::ECP(CryptoPP::ECP const&, bool) 
(ecp.cpp:32)
==26182==    by 0xA51A6D2: 
CryptoPP::EcPrecomputation<CryptoPP::ECP>::SetCurve(CryptoPP::ECP const&) 
(ecp.h:115)
==26182==    by 0xA51FA75: 
CryptoPP::DL_GroupParameters_EC<CryptoPP::ECP>::Initialize(CryptoPP::OID 
const&) (eccrypto.cpp:433)
==26182==    by 0xA520799: 
CryptoPP::DL_GroupParameters_EC<CryptoPP::ECP>::DL_GroupParameters_EC(CryptoPP::OID
 const&) (eccrypto.h:37)
==26182==    by 0xA620706: ??? (ecdsamodule.cpp:289)
==26182==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==26182==
==26182== Process terminating with default action of signal 11 (SIGSEGV)
==26182==  Bad permissions for mapped region at address 0x0
==26182==    at 0x0: ???
==26182==    by 0x9D1B722: CryptoPP::AsymmetricMultiply(unsigned long long*, 
unsigned long long*, unsigned long long const*, unsigned long, unsigned long 
long const*, unsigned long) (integer.cpp:2199)
==26182==    by 0x9D1C5C1: CryptoPP::Divide(unsigned long long*, unsigned long 
long*, unsigned long long*, unsigned long long const*, unsigned long, unsigned 
long long const*, unsigned long) (integer.cpp:2538)
==26182==    by 0x9D1D8EB: CryptoPP::PositiveDivide(CryptoPP::Integer&, 
CryptoPP::Integer&, CryptoPP::Integer const&, CryptoPP::Integer const&) 
(integer.cpp:3741)
==26182==    by 0x9D1D932: CryptoPP::Integer::Divide(CryptoPP::Integer&, 
CryptoPP::Integer&, CryptoPP::Integer const&, CryptoPP::Integer const&) 
(integer.cpp:3746)
==26182==    by 0x9D1DA00: CryptoPP::Integer::Modulo(CryptoPP::Integer const&) 
const (integer.cpp:3800)
==26182==    by 0x9C58C30: 
CryptoPP::MontgomeryRepresentation::ConvertIn(CryptoPP::Integer const&) const 
(modarith.h:132)
==26182==    by 0xA574DC6: CryptoPP::ECP::ECP(CryptoPP::ECP const&, bool) 
(ecp.cpp:32)
==26182==    by 0xA51A6D2: 
CryptoPP::EcPrecomputation<CryptoPP::ECP>::SetCurve(CryptoPP::ECP const&) 
(ecp.h:115)
==26182==    by 0xA51FA75: 
CryptoPP::DL_GroupParameters_EC<CryptoPP::ECP>::Initialize(CryptoPP::OID 
const&) (eccrypto.cpp:433)
==26182==    by 0xA520799: 
CryptoPP::DL_GroupParameters_EC<CryptoPP::ECP>::DL_GroupParameters_EC(CryptoPP::OID
 const&) (eccrypto.h:37)
==26182==    by 0xA620706: ??? (ecdsamodule.cpp:289)
==26182==
==26182== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 9656 from 9)
==26182== malloc/free: in use at exit: 16,310,629 bytes in 26,717 blocks.
==26182== malloc/free: 88,524 allocs, 61,807 frees, 171,746,080 bytes allocated.
==26182== For counts of detected errors, rerun with: -v
==26182== searching for pointers to 26,717 not-freed blocks.
==26182== checked 15,993,824 bytes.
==26182==
==26182== LEAK SUMMARY:
==26182==    definitely lost: 28 bytes in 1 blocks.
==26182==      possibly lost: 224,148 bytes in 456 blocks.
==26182==    still reachable: 16,086,453 bytes in 26,260 blocks.
==26182==         suppressed: 0 bytes in 0 blocks.
==26182== Rerun with --leak-check=full to see details of leaked memory.
Segmentation fault

_______________________________________________
tahoe-dev mailing list
[email protected]
http://allmydata.org/cgi-bin/mailman/listinfo/tahoe-dev

Reply via email to