abedra / libvault

A C++ library for Hashicorp Vault
MIT License
34 stars 25 forks source link

libvault crashes while attempting double-free #113

Closed bsbontchev closed 1 year ago

bsbontchev commented 1 year ago

Environment: Rocky 8, curl 7.61.1, libvault-0.52.0, Vault v1.8.2 Issue: After executing a VAULT request the libvault crashes due to memory corruption.

libvault.tar.gz When executing the attached program it crashes:

With out ASAN:

Connecting to : 127.0.0.1:8222

Trying 127.0.0.1...

TCP_NODELAY set

Connected to 127.0.0.1 (127.0.0.1) port 8222 (#0)

GET /v1/sys/seal-status HTTP/1.1 Host: 127.0.0.1:8222 Accept: / X-Vault-Token: token Content-Type: application/json

< HTTP/1.1 200 OK < Cache-Control: no-store < Content-Type: application/json < Date: Tue, 11 Apr 2023 18:45:43 GMT < Content-Length: 168 <

Connection #0 to host 127.0.0.1 left intact response : {"type":"shamir","initialized":false,"sealed":true,"t":0,"n":0,"progress":0,"nonce":"","version":"1.8.2","migration":false,"recovery_seal":false,"storage_type":"file"}

malloc(): unsorted double linked list corrupted Aborted (core dumped)

With ASAN:

Connecting to : 127.0.0.1:8222

Trying 127.0.0.1...

TCP_NODELAY set

Connected to 127.0.0.1 (127.0.0.1) port 8222 (#0)

GET /v1/sys/seal-status HTTP/1.1 Host: 127.0.0.1:8222 Accept: / X-Vault-Token: token Content-Type: application/json

< HTTP/1.1 200 OK < Cache-Control: no-store < Content-Type: application/json < Date: Tue, 11 Apr 2023 18:53:41 GMT < Content-Length: 168 <

Connection #0 to host 127.0.0.1 left intact

==2255562==ERROR: AddressSanitizer: attempting double-free on 0x604000000710 in thread T0:

0 0x7ff20de717e0 in __interceptor_free (/lib64/libasan.so.5+0xef7e0)

1 0x7ff20d1fbb69 (/lib64/libcurl.so.4+0x22b69)

2 0x7ff20d1fbe1e (/lib64/libcurl.so.4+0x22e1e)

3 0x7ff20d20a2e0 in curl_easy_cleanup (/lib64/libcurl.so.4+0x312e0)

4 0x7ff20cf5c48a in Vault::HttpClient::CurlWrapper::~CurlWrapper() (libvault.so.0+0x12248a)

5 0x7ff20cf5917f in Vault::HttpClient::executeRequest(Vault::Tiny<Vault::UrlDetail, std::cxx11::basic_string<char, std::char_traits, std::allocator > > const&, Vault::Tiny<Vault::TokenDetail, std::cxx11::basic_string<char, std::char_traits, std::allocator > > const&, Vault::Tiny<Vault::NamespaceDetail, std::cxx11::basic_string<char, std::char_traits, std::allocator > > const&, std::function<void (void)> const&, std::function<curl_slist (curl_slist*)> const&, std::function<void (std::cxx11::basic_string<char, std::char_traits, std::allocator >)> const&) const (libvault.so.0+0x11f17f)

6 0x7ff20cf585b5 in Vault::HttpClient::get(Vault::Tiny<Vault::UrlDetail, std::cxx11::basic_string<char, std::char_traits, std::allocator > > const&, Vault::Tiny<Vault::TokenDetail, std::cxx11::basic_string<char, std::char_traits, std::allocator > > const&, Vault::Tiny<Vault::NamespaceDetail, std::__cxx11::basic_string<char, std::char_traits, std::allocator > > const&) const (libvault.so.0+0x11e5b5)

7 0x7ff20cf5d42c in Vault::HttpConsumer::get(Vault::Client const&, Vault::Tiny<Vault::UrlDetail, std::__cxx11::basic_string<char, std::char_traits, std::allocator > > const&) (libvault.so.0+0x12342c)

8 0x7ff20cf734a3 in Vault::Sys::sealStatusabi:cxx11%20AND%20statusCategory%20in%20(%22To%20Do%22%2C%20%22In%20Progress%22)%20AND%20status%20IN%20(%22Open%22%2C%22In%20Development%22)%20ORDER%20BY%20created%20DESC) (libvault.so.0+0x1394a3)

9 0x41d76f in SecureStorage::status() src/securestorage.cpp:67

10 0x41d345 in SecureStorage::connect() src/securestorage.cpp:42

11 0x41f30e in main src/securestorage.cpp:150

12 0x7ff20c897cf2 in __libc_start_main (/lib64/libc.so.6+0x3acf2)

13 0x41c85d in _start (/root/bbontchev/test/vault/test+0x41c85d)

0x604000000710 is located 0 bytes inside of 41-byte region [0x604000000710,0x604000000739) freed by thread T0 here:

0 0x7ff20de74688 in operator delete(void*) (/lib64/libasan.so.5+0xf2688)

#1 0x429899 in __gnu_cxx::new_allocator<char>::deallocate(char*, unsigned long) /usr/include/c++/8/ext/new_allocator.h:125
#2 0x427706 in std::allocator_traits<std::allocator<char> >::deallocate(std::allocator<char>&, char*, unsigned long) /usr/include/c++/8/bits/alloc_traits.h:462
#3 0x4253a7 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_destroy(unsigned long) /usr/include/c++/8/bits/basic_string.h:226
#4 0x424e24 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_dispose() /usr/include/c++/8/bits/basic_string.h:221
#5 0x422573 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() /usr/include/c++/8/bits/basic_string.h:657
#6 0x7ff20cf5c830 in Vault::HttpClient::CurlWrapper::execute() const (libvault.so.0+0x122830)
#7 0x7ff20cf5916f in Vault::HttpClient::executeRequest(Vault::Tiny<Vault::UrlDetail, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, Vault::Tiny<Vault::TokenDetail, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, Vault::Tiny<Vault::NamespaceDetail, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, std::function<void (void*)> const&, std::function<curl_slist* (curl_slist*)> const&, std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)> const&) const (libvault.so.0+0x11f16f)
#8 0x7ff20cf585b5 in Vault::HttpClient::get(Vault::Tiny<Vault::UrlDetail, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, Vault::Tiny<Vault::TokenDetail, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, Vault::Tiny<Vault::NamespaceDetail, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&) const (libvault.so.0+0x11e5b5)
#9 0x7ff20cf5d42c in Vault::HttpConsumer::get(Vault::Client const&, Vault::Tiny<Vault::UrlDetail, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&) (libvault.so.0+0x12342c)
#10 0x7ff20cf734a3 in Vault::Sys::sealStatus[abi:cxx11](https://enghouseglobal.atlassian.net/jira/software/c/projects/XMS/issues/XMS-15860?jql=project%20%3D%20%22XMS%22%20AND%20assignee%20IN%20(currentUser())%20AND%20statusCategory%20in%20(%22To%20Do%22%2C%20%22In%20Progress%22)%20AND%20status%20IN%20(%22Open%22%2C%22In%20Development%22)%20ORDER%20BY%20created%20DESC) (libvault.so.0+0x1394a3)
#11 0x41d76f in SecureStorage::status() src/securestorage.cpp:67
#12 0x41d345 in SecureStorage::connect() src/securestorage.cpp:42
#13 0x41f30e in main src/securestorage.cpp:150
#14 0x7ff20c897cf2 in __libc_start_main (/lib64/libc.so.6+0x3acf2)

previously allocated by thread T0 here:

0 0x7ff20ddbdda0 in strdup (/lib64/libasan.so.5+0x3bda0)

#1 0x7ff20d2351ad  (/lib64/libcurl.so.4+0x5c1ad)

SUMMARY: AddressSanitizer: double-free (/lib64/libasan.so.5+0xef7e0) in __interceptor_free ==2255562==ABORTING Aborted (core dumped)

Most probably the issue is due to the following code: std::string url; curl_easygetinfo(curl, CURLINFO_EFFECTIVE_URL, &url);

abedra commented 1 year ago

This was fixed in https://github.com/abedra/libvault/commit/428dca23384220ef7ebf863892de699ef239bc9d. It looks like I didn't cut another release, so i'll get 0.53.0 out but you can use the master branch in the mean time

abedra commented 1 year ago

https://github.com/abedra/libvault/releases/tag/0.53.0

bsbontchev commented 1 year ago

Thanks. I will. Can you fix the others before making a release as they are security related?