[ https://issues.apache.org/jira/browse/PROTON-1556?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16201294#comment-16201294 ]
Cliff Jansen commented on PROTON-1556: -------------------------------------- The last fix is a safe band-aid. Leaving the JIRA unresolved until more time to revisit if there was a reason the old copy and swap code was replaced. > [proton-cpp] ssl_client_options is not self-assignable > ------------------------------------------------------ > > Key: PROTON-1556 > URL: https://issues.apache.org/jira/browse/PROTON-1556 > Project: Qpid Proton > Issue Type: Bug > Components: cpp-binding > Affects Versions: proton-c-0.18.0 > Reporter: Jiri Daněk > Assignee: Cliff Jansen > Priority: Critical > Fix For: proton-c-0.19.0 > > Attachments: report-7646dc.html > > > {{ssl_client_options}} probably cannot be self-assigned. See the attached > report from clang-analyzer, which looks very plausible. > The problem is that assuming {{x == *this}}, the assignment operator will > decref and then incref the same value. Assuming the reference count was {{1}} > to start with, there will be use-after-free. > This probably does not matter that much in real-world code, but I found some > quotations that making self assignment work is really important in C++... > {noformat} > 58 ssl_domain& internal::ssl_domain::operator=(const ssl_domain&x) { > 59 if (impl_) impl_->decref(); > 60 impl_ = x.impl_; > 61 server_type_ = x.server_type_; > 62 if (impl_) impl_->incref(); > 63 return *this; > 64 } > {noformat} > I believe the static analyzer is correct, because when I do not make any > changes to the {{examples/cpp/ssl}} example, Valgrind does not report errors > concerning the class, but if I add a {{ssl_cli = ssl_cli;}}, then I get > {noformat} > $ valgrind ./ssl -c > /home/jdanek/Work/repos/qpid-proton/examples/cpp/ssl_certs/ > ==4950== Memcheck, a memory error detector > ==4950== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. > ==4950== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info > ==4950== Command: ./ssl -c > /home/jdanek/Work/repos/qpid-proton/examples/cpp/ssl_certs/ > ==4950== > ==4950== Invalid read of size 4 > ==4950== at 0x4E715CC: incref (ssl_domain.cpp:37) > ==4950== by 0x4E715CC: > proton::internal::ssl_domain::operator=(proton::internal::ssl_domain const&) > (ssl_domain.cpp:62) > ==4950== by 0x4032F0: operator= (ssl.hpp:172) > ==4950== by 0x4032F0: main (ssl.cpp:176) > ==4950== Address 0x766a3c0 is 0 bytes inside a block of size 16 free'd > ==4950== at 0x4C2D2EB: operator delete(void*) (in > /nix/store/gv9x2j31hvn0wf37h4jmb9xz6vgc3vvv-valgrind-3.12.0/lib/valgrind/vgpreload_memcheck-amd64-linux.so) > ==4950== by 0x4E715FA: decref (ssl_domain.cpp:40) > ==4950== by 0x4E715FA: > proton::internal::ssl_domain::operator=(proton::internal::ssl_domain const&) > (ssl_domain.cpp:59) > ==4950== by 0x4032F0: operator= (ssl.hpp:172) > ==4950== by 0x4032F0: main (ssl.cpp:176) > ==4950== Block was alloc'd at > ==4950== at 0x4C2C22F: operator new(unsigned long) (in > /nix/store/gv9x2j31hvn0wf37h4jmb9xz6vgc3vvv-valgrind-3.12.0/lib/valgrind/vgpreload_memcheck-amd64-linux.so) > ==4950== by 0x4E7166C: proton::internal::ssl_domain::pn_domain() > (ssl_domain.cpp:72) > ==4950== by 0x4E7195C: > proton::ssl_client_options::ssl_client_options(std::__cxx11::basic_string<char, > std::char_traits<char>, std::allocator<char> > const&, > proton::ssl::verify_mode) (ssl_domain.cpp:120) > ==4950== by 0x4032B9: main (ssl.cpp:175) > ==4950== > ==4950== Invalid read of size 4 > ==4950== at 0x4E71619: decref (ssl_domain.cpp:39) > ==4950== by 0x4E71619: proton::internal::ssl_domain::~ssl_domain() > (ssl_domain.cpp:66) > ==4950== by 0x4032F8: ~ssl_client_options (ssl.hpp:172) > ==4950== by 0x4032F8: main (ssl.cpp:175) > ==4950== Address 0x766a3c0 is 0 bytes inside a block of size 16 free'd > ==4950== at 0x4C2D2EB: operator delete(void*) (in > /nix/store/gv9x2j31hvn0wf37h4jmb9xz6vgc3vvv-valgrind-3.12.0/lib/valgrind/vgpreload_memcheck-amd64-linux.so) > ==4950== by 0x4E715FA: decref (ssl_domain.cpp:40) > ==4950== by 0x4E715FA: > proton::internal::ssl_domain::operator=(proton::internal::ssl_domain const&) > (ssl_domain.cpp:59) > ==4950== by 0x4032F0: operator= (ssl.hpp:172) > ==4950== by 0x4032F0: main (ssl.cpp:176) > ==4950== Block was alloc'd at > ==4950== at 0x4C2C22F: operator new(unsigned long) (in > /nix/store/gv9x2j31hvn0wf37h4jmb9xz6vgc3vvv-valgrind-3.12.0/lib/valgrind/vgpreload_memcheck-amd64-linux.so) > ==4950== by 0x4E7166C: proton::internal::ssl_domain::pn_domain() > (ssl_domain.cpp:72) > ==4950== by 0x4E7195C: > proton::ssl_client_options::ssl_client_options(std::__cxx11::basic_string<char, > std::char_traits<char>, std::allocator<char> > const&, > proton::ssl::verify_mode) (ssl_domain.cpp:120) > ==4950== by 0x4032B9: main (ssl.cpp:175) > ==4950== > ==4950== Invalid read of size 8 > ==4950== at 0x4E71620: ~ssl_domain_impl (ssl_domain.cpp:36) > ==4950== by 0x4E71620: decref (ssl_domain.cpp:40) > ==4950== by 0x4E71620: proton::internal::ssl_domain::~ssl_domain() > (ssl_domain.cpp:66) > ==4950== by 0x4032F8: ~ssl_client_options (ssl.hpp:172) > ==4950== by 0x4032F8: main (ssl.cpp:175) > ==4950== Address 0x766a3c8 is 8 bytes inside a block of size 16 free'd > ==4950== at 0x4C2D2EB: operator delete(void*) (in > /nix/store/gv9x2j31hvn0wf37h4jmb9xz6vgc3vvv-valgrind-3.12.0/lib/valgrind/vgpreload_memcheck-amd64-linux.so) > ==4950== by 0x4E715FA: decref (ssl_domain.cpp:40) > ==4950== by 0x4E715FA: > proton::internal::ssl_domain::operator=(proton::internal::ssl_domain const&) > (ssl_domain.cpp:59) > ==4950== by 0x4032F0: operator= (ssl.hpp:172) > ==4950== by 0x4032F0: main (ssl.cpp:176) > ==4950== Block was alloc'd at > ==4950== at 0x4C2C22F: operator new(unsigned long) (in > /nix/store/gv9x2j31hvn0wf37h4jmb9xz6vgc3vvv-valgrind-3.12.0/lib/valgrind/vgpreload_memcheck-amd64-linux.so) > ==4950== by 0x4E7166C: proton::internal::ssl_domain::pn_domain() > (ssl_domain.cpp:72) > ==4950== by 0x4E7195C: > proton::ssl_client_options::ssl_client_options(std::__cxx11::basic_string<char, > std::char_traits<char>, std::allocator<char> > const&, > proton::ssl::verify_mode) (ssl_domain.cpp:120) > ==4950== by 0x4032B9: main (ssl.cpp:175) > ==4950== > ==4950== Invalid read of size 4 > ==4950== at 0x52B8840: pn_ssl_domain_free (openssl.c:559) > ==4950== by 0x4E71628: ~ssl_domain_impl (ssl_domain.cpp:36) > ==4950== by 0x4E71628: decref (ssl_domain.cpp:40) > ==4950== by 0x4E71628: proton::internal::ssl_domain::~ssl_domain() > (ssl_domain.cpp:66) > ==4950== by 0x4032F8: ~ssl_client_options (ssl.hpp:172) > ==4950== by 0x4032F8: main (ssl.cpp:175) > ==4950== Address 0x76c1c08 is 24 bytes inside a block of size 40 free'd > ==4950== at 0x4C2CDEB: free (in > /nix/store/gv9x2j31hvn0wf37h4jmb9xz6vgc3vvv-valgrind-3.12.0/lib/valgrind/vgpreload_memcheck-amd64-linux.so) > ==4950== by 0x4E715ED: ~ssl_domain_impl (ssl_domain.cpp:36) > ==4950== by 0x4E715ED: decref (ssl_domain.cpp:40) > ==4950== by 0x4E715ED: > proton::internal::ssl_domain::operator=(proton::internal::ssl_domain const&) > (ssl_domain.cpp:59) > ==4950== by 0x4032F0: operator= (ssl.hpp:172) > ==4950== by 0x4032F0: main (ssl.cpp:176) > ==4950== Block was alloc'd at > ==4950== at 0x4C2DBD5: calloc (in > /nix/store/gv9x2j31hvn0wf37h4jmb9xz6vgc3vvv-valgrind-3.12.0/lib/valgrind/vgpreload_memcheck-amd64-linux.so) > ==4950== by 0x52B8C26: pn_ssl_domain (openssl.c:490) > ==4950== by 0x4E71BB9: proton::ssl_domain_impl::ssl_domain_impl(bool) > (ssl_domain.cpp:33) > ==4950== by 0x4E7167B: proton::internal::ssl_domain::pn_domain() > (ssl_domain.cpp:72) > ==4950== by 0x4E7195C: > proton::ssl_client_options::ssl_client_options(std::__cxx11::basic_string<char, > std::char_traits<char>, std::allocator<char> > const&, > proton::ssl::verify_mode) (ssl_domain.cpp:120) > ==4950== by 0x4032B9: main (ssl.cpp:175) > ==4950== > ==4950== Invalid free() / delete / delete[] / realloc() > ==4950== at 0x4C2D2EB: operator delete(void*) (in > /nix/store/gv9x2j31hvn0wf37h4jmb9xz6vgc3vvv-valgrind-3.12.0/lib/valgrind/vgpreload_memcheck-amd64-linux.so) > ==4950== by 0x4032F8: ~ssl_client_options (ssl.hpp:172) > ==4950== by 0x4032F8: main (ssl.cpp:175) > ==4950== Address 0x766a3c0 is 0 bytes inside a block of size 16 free'd > ==4950== at 0x4C2D2EB: operator delete(void*) (in > /nix/store/gv9x2j31hvn0wf37h4jmb9xz6vgc3vvv-valgrind-3.12.0/lib/valgrind/vgpreload_memcheck-amd64-linux.so) > ==4950== by 0x4E715FA: decref (ssl_domain.cpp:40) > ==4950== by 0x4E715FA: > proton::internal::ssl_domain::operator=(proton::internal::ssl_domain const&) > (ssl_domain.cpp:59) > ==4950== by 0x4032F0: operator= (ssl.hpp:172) > ==4950== by 0x4032F0: main (ssl.cpp:176) > ==4950== Block was alloc'd at > ==4950== at 0x4C2C22F: operator new(unsigned long) (in > /nix/store/gv9x2j31hvn0wf37h4jmb9xz6vgc3vvv-valgrind-3.12.0/lib/valgrind/vgpreload_memcheck-amd64-linux.so) > ==4950== by 0x4E7166C: proton::internal::ssl_domain::pn_domain() > (ssl_domain.cpp:72) > ==4950== by 0x4E7195C: > proton::ssl_client_options::ssl_client_options(std::__cxx11::basic_string<char, > std::char_traits<char>, std::allocator<char> > const&, > proton::ssl::verify_mode) (ssl_domain.cpp:120) > ==4950== by 0x4032B9: main (ssl.cpp:175) > ==4950== > ==4950== > ==4950== HEAP SUMMARY: > ==4950== in use at exit: 98,536 bytes in 3,275 blocks > ==4950== total heap usage: 3,651 allocs, 377 frees, 237,715 bytes allocated > ==4950== > ==4950== LEAK SUMMARY: > ==4950== definitely lost: 0 bytes in 0 blocks > ==4950== indirectly lost: 0 bytes in 0 blocks > ==4950== possibly lost: 0 bytes in 0 blocks > ==4950== still reachable: 98,536 bytes in 3,275 blocks > ==4950== suppressed: 0 bytes in 0 blocks > ==4950== Rerun with --leak-check=full to see details of leaked memory > ==4950== > ==4950== For counts of detected and suppressed errors, rerun with: -v > ==4950== ERROR SUMMARY: 8 errors from 5 contexts (suppressed: 0 from 0) > {noformat} > Hat tip to [~rkubis] for help with C++. -- This message was sent by Atlassian JIRA (v6.4.14#64029) --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@qpid.apache.org For additional commands, e-mail: dev-h...@qpid.apache.org