Open ctpo6 opened 8 years ago
Hello!
I have addressed some issues with "enable_shared_from_this", and also moved it to the only classes where it is actually required (mainly the ones in the "net" namespace). I have also fixed some ambiguities about how some classes should be instantiated because of this (heap/stack).
Here is the related commit: b1c2d4b
Vincent,
I'm test this commit and crash my service. This happens when I load my certificates
Before commit, this worked well
vmime::shared_ptrvmime::security::cert::X509Certificate CopyCert(vmime::shared_ptrvmime::security::cert::X509Certificate cert) { stringstream ss; vmime::utility::outputStreamAdapter out(ss); cert->write(out, vmime::security::cert::X509Certificate::FORMAT_PEM); vmime::utility::inputStreamAdapter in(ss); return vmime::security::cert::X509Certificate::import (in); }
**
vmime::shared_ptrvmime::security::cert::defaultCertificateVerifier CCertificateHandler::getCertificateVerifier(const std::string& url) {
vmime::shared_ptr
boost::mutex::scoped_lock lock (m_mutex);
std::vector<vmime::shared_ptr<vmime::security::cert::X509Certificate> > certificados;
for (unsigned int i = 0; i < m_certificates.size(); i++) {
certificados.push_back(CopyCert(m_certificates[i]));
}
vrf->setX509RootCAs(certificados); <= THIS LINE =>
vrf->setX509TrustedCerts(certificados);
return vrf;
} **
This is the core:
at /usr/local/include/boost-1_44/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp:50
50 /usr/local/include/boost-1_44/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp: No such file or directory. in /usr/local/include/boost-1_44/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp (gdb) bt
at /usr/local/include/boost-1_44/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp:50
at /usr/local/include/boost-1_44/boost/smart_ptr/detail/sp_counted_base_gcc_x86.hpp:143
at /root/integration-build/sources/emailproxy/src/libvmime-master/src/vmime/security/cert/defaultCertificateVerifier.cpp:162
at /usr/local/include/boost-1_44/boost/bind/mem_fn_template.hpp:165
at /usr/local/include/boost-1_44/boost/function/function_template.hpp:153
Hello! I'm currently investigating on this issue...
I'm not able to reproduce your issue with the latest VMime code from today. Maybe there is some other code of your own that is involved in the problem?
As far as I understand, the crash occurs when copying a std::vector
of shared_ptr <X509Certificate>
, that's what I tried to reproduce.
Here is the test program I used (also ran it through gdb and Valgrind):
#include <iostream>
#include <fstream>
#include "vmime/vmime.hpp"
#include "vmime/platforms/posix/posixHandler.hpp"
vmime::shared_ptr <vmime::security::cert::X509Certificate> CopyCert(
vmime::shared_ptr <vmime::security::cert::X509Certificate> cert
) {
std::stringstream ss;
vmime::utility::outputStreamAdapter out(ss);
cert->write(out, vmime::security::cert::X509Certificate::FORMAT_PEM);
vmime::utility::inputStreamAdapter in(ss);
return vmime::security::cert::X509Certificate::import(in);
}
int main() {
const char *certs[] = {
// Put paths to any certificates here...
"/usr/share/ca-certificates/mozilla/QuoVadis_Root_CA_3.crt",
"/usr/share/ca-certificates/mozilla/NetLock_Notary_=Class_A=_Root.crt",
"/usr/share/ca-certificates/mozilla/SwissSign_Silver_CA_-_G2.crt",
"/usr/share/ca-certificates/mozilla/TWCA_Root_Certification_Authority.crt",
};
// Test adding certificates
std::vector <vmime::shared_ptr <vmime::security::cert::X509Certificate> > certificates;
for (unsigned i = 0 ; i < sizeof(certs) / sizeof(certs[0]) ; ++i) {
std::ifstream is(certs[i]);
vmime::utility::inputStreamAdapter vis(is);
vmime::shared_ptr <vmime::security::cert::X509Certificate> cert =
vmime::security::cert::X509Certificate::import(vis);
certificates.push_back(CopyCert(cert));
}
vmime::shared_ptr <vmime::security::cert::defaultCertificateVerifier> vrf =
vmime::make_shared <vmime::security::cert::defaultCertificateVerifier>();
vrf->setX509RootCAs(certificates);
vrf->setX509TrustedCerts(certificates);
// Test copying vector
std::vector <vmime::shared_ptr <vmime::security::cert::X509Certificate> > certificatesCopy = certificates;
std::cout << "count = " << certificatesCopy.size() << std::endl;
// Test using object
std::vector <vmime::shared_ptr <vmime::security::cert::certificate> > certificates2;
for (unsigned i = 0 ; i < certificates.size() ; ++i) {
certificates2.push_back(certificates[i]);
}
vmime::shared_ptr <vmime::security::cert::certificateChain> chain =
vmime::make_shared <vmime::security::cert::certificateChain>(certificates2);
try {
vrf->verify(chain, "test.com");
} catch (vmime::exception &e) {
// verify() will fail
}
return 0;
}
Mmmm ok Vincent, I will review again.
It's a really very dangerous bug in the core of library: vmime::object and vmime::net::folderAttributes classes have a flawed copy ctor. The same with operator=(). Because vmime::object is inherited from enable_shared_from_this, it's copy ctor operator=() MUST call inherited ones, but they don't, which leads to garbaged inner weak_ptr with unpredictable consequences. I had got a very nasty memleak in a daemon, not detectable even with valgrind. In my fork of vmime, which I'd made C++11 only, I defined copy ctor and operator=() of these classes as =default.