You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@qpid.apache.org by "Jiri Danek (JIRA)" <ji...@apache.org> on 2017/08/25 11:08:00 UTC

[jira] [Created] (PROTON-1556) [proton=cpp] ssl_client_options is not self-assignable

Jiri Danek created PROTON-1556:
----------------------------------

             Summary: [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 Danek
            Assignee: Cliff Jansen
            Priority: Trivial
         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, 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-unsubscribe@qpid.apache.org
For additional commands, e-mail: dev-help@qpid.apache.org