wazuh / wazuh-http-request

Wazuh HTTP request library
7 stars 6 forks source link

Multi-handler request fail if executed twice #63

Closed pereyra-m closed 2 months ago

pereyra-m commented 3 months ago

Description

During the testing of #61, it was found that the internal handler is added to the multi-handler in each execution https://github.com/wazuh/wazuh-http-request/blob/314f6edc5c5e44af63c19135bfa7f704ee9cdfe2/src/curlMultiHandler.hpp#L71

Resulting in the following failed test

Details

```c++ TEST_F(ComponentTestInterface, DownloadTestTimeoutMultiHandler) { std::atomic shouldRun {true}; EXPECT_NO_THROW({ HTTPRequest::instance().download( HttpURL("http://localhost:44441"), "./test1.txt", [](auto a, auto) { std::cout << a << std::endl; }, {}, {}, {}, CurlHandlerTypeEnum::MULTI, shouldRun); }); EXPECT_NO_THROW({ HTTPRequest::instance().download( HttpURL("http://localhost:44441"), "./test2.txt", [](auto a, auto) { std::cout << a << std::endl; }, {}, {}, {}, CurlHandlerTypeEnum::MULTI, shouldRun); }); std::ifstream file1("./test1.txt"); std::string line1; std::getline(file1, line1); EXPECT_EQ(line1, "Hello World!"); std::ifstream file2("./test2.txt"); std::string line2; std::getline(file2, line2); EXPECT_EQ(line2, "Hello World!"); } ``` ``` oot@6f68a3e7a4f3:/workspaces/wazuh-temp/main/build# ./test/component/urlrequest_component_test --gtest_filter=*DownloadTestTimeoutMultiHandler* Note: Google Test filter = *DownloadTestTimeoutMultiHandler* [==========] Running 1 test from 1 test suite. [----------] Global test environment set-up. [----------] 1 test from ComponentTestInterface [ RUN ] ComponentTestInterface.DownloadTestTimeoutMultiHandler cURLMultiHandler::execute() failed: curl_multi_add_handle: The easy handle is already added to a multi handle /workspaces/wazuh-temp/main/test/component/component_test.cpp:1099: Failure Expected equality of these values: line2 Which is: "" "Hello World!" [ FAILED ] ComponentTestInterface.DownloadTestTimeoutMultiHandler (2 ms) [----------] 1 test from ComponentTestInterface (2 ms total) [----------] Global test environment tear-down [==========] 1 test from 1 test suite ran. (4 ms total) [ PASSED ] 0 tests. [ FAILED ] 1 test, listed below: [ FAILED ] ComponentTestInterface.DownloadTestTimeoutMultiHandler 1 FAILED TEST ``` **Note**: the following line was modified to add more detail in the error https://github.com/wazuh/wazuh-http-request/blob/314f6edc5c5e44af63c19135bfa7f704ee9cdfe2/src/curlMultiHandler.hpp#L75 ```c++ throw std::runtime_error("cURLMultiHandler::execute() failed: curl_multi_add_handle: " + std::string(curl_multi_strerror(multiCode))); ```

DoD

pereyra-m commented 3 months ago

Update

I begin with the RCA to identify all the required changes.

pereyra-m commented 3 months ago

Update

It was found that easy handler is never removed from the multi handler, so after the first execute(), it'll always fail.

I continue with the MULTI handler class fix, testing the normal and the timeout request.

pereyra-m commented 3 months ago

Update

I continue working on the pre-existent error with the MULTI handler. I'm analyzing the results of the adress-sanitizer report.

Details

``` root@6f68a3e7a4f3:/workspaces/wazuh-http-request/build/test/component# ./urlrequest_component_test --gtest_filter=*Multi* Note: Google Test filter = *Multi* [==========] Running 12 tests from 2 test suites. [----------] Global test environment set-up. [----------] 10 tests from ComponentTestInterface [ RUN ] ComponentTestInterface.DownloadFileUsingTheMultiHandler curlHandlerInit: 1 cURLMultiHandler created: 1 curlWrapper after Init: 1 cURLMultiHandler::execute() started: 1 [ OK ] ComponentTestInterface.DownloadFileUsingTheMultiHandler (3 ms) [ RUN ] ComponentTestInterface.InterruptMultiHandler /workspaces/wazuh-http-request/test/component/component_test.cpp:261: Skipped This test is skipped because it is not working properly. [ SKIPPED ] ComponentTestInterface.InterruptMultiHandler (0 ms) [ RUN ] ComponentTestInterface.DownloadFileEmptyURLUsingTheMultiHandler /workspaces/wazuh-http-request/test/component/component_test.cpp:316: Skipped This test is skipped because it is not working properly. [ SKIPPED ] ComponentTestInterface.DownloadFileEmptyURLUsingTheMultiHandler (0 ms) [ RUN ] ComponentTestInterface.DownloadFileErrorUsingTheMultiHandler /workspaces/wazuh-http-request/test/component/component_test.cpp:341: Skipped This test is skipped because it is not working properly. [ SKIPPED ] ComponentTestInterface.DownloadFileErrorUsingTheMultiHandler (0 ms) [ RUN ] ComponentTestInterface.DownloadTestTimeoutMultiHandler Test the DOWNLOAD request with timeout for MULTI handler: 1 curlHandlerInit: 1 curlWrapper after Init: 1 ================================================================= ==2151==ERROR: AddressSanitizer: heap-use-after-free on address 0x603000007221 at pc 0x55ea814baf83 bp 0x7ffc8c0fa730 sp 0x7ffc8c0fa720 READ of size 1 at 0x603000007221 thread T0 #0 0x55ea814baf82 in std::__atomic_base::load(std::memory_order) const /usr/include/c++/11/bits/atomic_base.h:488 #1 0x55ea814baf82 in std::atomic::load(std::memory_order) const /usr/include/c++/11/atomic:112 #2 0x55ea814e527a in cURLMultiHandler::execute() /workspaces/wazuh-http-request/src/curlMultiHandler.hpp:72 #3 0x55ea814e83e7 in cURLWrapper::execute() /workspaces/wazuh-http-request/src/curlWrapper.hpp:198 #4 0x55ea815093e1 in cURLRequest::execute() /workspaces/wazuh-http-request/src/urlRequest.hpp:129 #5 0x55ea81621ff4 in HTTPRequest::download(RequestParameters, PostRequestParameters, ConfigurationParameters) /workspaces/wazuh-http-request/src/HTTPRequest.cpp:48 #6 0x55ea81477925 in ComponentTestInterface_DownloadTestTimeoutMultiHandler_Test::TestBody() /workspaces/wazuh-http-request/test/component/component_test.cpp:1027 #7 0x55ea816b8dab in void testing::internal::HandleSehExceptionsInMethodIfSupported(testing::Test*, void (testing::Test::*)(), char const*) /workspaces/wazuh-http-request/external/googletest/googletest/src/gtest.cc:2607 #8 0x55ea816a8371 in void testing::internal::HandleExceptionsInMethodIfSupported(testing::Test*, void (testing::Test::*)(), char const*) /workspaces/wazuh-http-request/external/googletest/googletest/src/gtest.cc:2643 #9 0x55ea81641825 in testing::Test::Run() /workspaces/wazuh-http-request/external/googletest/googletest/src/gtest.cc:2682 #10 0x55ea81642e45 in testing::TestInfo::Run() /workspaces/wazuh-http-request/external/googletest/googletest/src/gtest.cc:2861 #11 0x55ea81644042 in testing::TestSuite::Run() /workspaces/wazuh-http-request/external/googletest/googletest/src/gtest.cc:3015 #12 0x55ea8166a41a in testing::internal::UnitTestImpl::RunAllTests() /workspaces/wazuh-http-request/external/googletest/googletest/src/gtest.cc:5855 #13 0x55ea816bba23 in bool testing::internal::HandleSehExceptionsInMethodIfSupported(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /workspaces/wazuh-http-request/external/googletest/googletest/src/gtest.cc:2607 #14 0x55ea816aae30 in bool testing::internal::HandleExceptionsInMethodIfSupported(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /workspaces/wazuh-http-request/external/googletest/googletest/src/gtest.cc:2643 #15 0x55ea81666d8b in testing::UnitTest::Run() /workspaces/wazuh-http-request/external/googletest/googletest/src/gtest.cc:5438 #16 0x55ea81621aee in RUN_ALL_TESTS() /workspaces/wazuh-http-request/external/googletest/googletest/include/gtest/gtest.h:2490 #17 0x55ea816219b9 in main /workspaces/wazuh-http-request/test/component/main.cpp:17 #18 0x7f2ade2edd8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 #19 0x7f2ade2ede3f in __libc_start_main_impl ../csu/libc-start.c:392 #20 0x55ea814421a4 in _start (/workspaces/wazuh-http-request/build/test/component/urlrequest_component_test+0x441a4) 0x603000007221 is located 17 bytes inside of 24-byte region [0x603000007210,0x603000007228) freed by thread T0 here: #0 0x7f2adeeb924f in operator delete(void*, unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:172 #1 0x55ea8161ba7e in ComponentTestInterface_DownloadFileUsingTheMultiHandler_Test::~ComponentTestInterface_DownloadFileUsingTheMultiHandler_Test() (/workspaces/wazuh-http-request/build/test/component/urlrequest_component_test+0x21da7e) #2 0x55ea81694cf6 in testing::Test::DeleteSelf_() /workspaces/wazuh-http-request/external/googletest/googletest/include/gtest/gtest.h:501 #3 0x55ea816b8dab in void testing::internal::HandleSehExceptionsInMethodIfSupported(testing::Test*, void (testing::Test::*)(), char const*) /workspaces/wazuh-http-request/external/googletest/googletest/src/gtest.cc:2607 #4 0x55ea816a8371 in void testing::internal::HandleExceptionsInMethodIfSupported(testing::Test*, void (testing::Test::*)(), char const*) /workspaces/wazuh-http-request/external/googletest/googletest/src/gtest.cc:2643 #5 0x55ea81642eed in testing::TestInfo::Run() /workspaces/wazuh-http-request/external/googletest/googletest/src/gtest.cc:2867 #6 0x55ea81644042 in testing::TestSuite::Run() /workspaces/wazuh-http-request/external/googletest/googletest/src/gtest.cc:3015 #7 0x55ea8166a41a in testing::internal::UnitTestImpl::RunAllTests() /workspaces/wazuh-http-request/external/googletest/googletest/src/gtest.cc:5855 #8 0x55ea816bba23 in bool testing::internal::HandleSehExceptionsInMethodIfSupported(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /workspaces/wazuh-http-request/external/googletest/googletest/src/gtest.cc:2607 #9 0x55ea816aae30 in bool testing::internal::HandleExceptionsInMethodIfSupported(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /workspaces/wazuh-http-request/external/googletest/googletest/src/gtest.cc:2643 #10 0x55ea81666d8b in testing::UnitTest::Run() /workspaces/wazuh-http-request/external/googletest/googletest/src/gtest.cc:5438 #11 0x55ea81621aee in RUN_ALL_TESTS() /workspaces/wazuh-http-request/external/googletest/googletest/include/gtest/gtest.h:2490 #12 0x55ea816219b9 in main /workspaces/wazuh-http-request/test/component/main.cpp:17 #13 0x7f2ade2edd8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 previously allocated by thread T0 here: #0 0x7f2adeeb81e7 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:99 #1 0x55ea81620ad4 in testing::internal::TestFactoryImpl::CreateTest() (/workspaces/wazuh-http-request/build/test/component/urlrequest_component_test+0x222ad4) #2 0x55ea816b90c5 in testing::Test* testing::internal::HandleSehExceptionsInMethodIfSupported(testing::internal::TestFactoryBase*, testing::Test* (testing::internal::TestFactoryBase::*)(), char const*) /workspaces/wazuh-http-request/external/googletest/googletest/src/gtest.cc:2607 #3 0x55ea816a8bd1 in testing::Test* testing::internal::HandleExceptionsInMethodIfSupported(testing::internal::TestFactoryBase*, testing::Test* (testing::internal::TestFactoryBase::*)(), char const*) /workspaces/wazuh-http-request/external/googletest/googletest/src/gtest.cc:2643 #4 0x55ea81642e07 in testing::TestInfo::Run() /workspaces/wazuh-http-request/external/googletest/googletest/src/gtest.cc:2851 #5 0x55ea81644042 in testing::TestSuite::Run() /workspaces/wazuh-http-request/external/googletest/googletest/src/gtest.cc:3015 #6 0x55ea8166a41a in testing::internal::UnitTestImpl::RunAllTests() /workspaces/wazuh-http-request/external/googletest/googletest/src/gtest.cc:5855 #7 0x55ea816bba23 in bool testing::internal::HandleSehExceptionsInMethodIfSupported(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /workspaces/wazuh-http-request/external/googletest/googletest/src/gtest.cc:2607 #8 0x55ea816aae30 in bool testing::internal::HandleExceptionsInMethodIfSupported(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /workspaces/wazuh-http-request/external/googletest/googletest/src/gtest.cc:2643 #9 0x55ea81666d8b in testing::UnitTest::Run() /workspaces/wazuh-http-request/external/googletest/googletest/src/gtest.cc:5438 #10 0x55ea81621aee in RUN_ALL_TESTS() /workspaces/wazuh-http-request/external/googletest/googletest/include/gtest/gtest.h:2490 #11 0x55ea816219b9 in main /workspaces/wazuh-http-request/test/component/main.cpp:17 #12 0x7f2ade2edd8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 SUMMARY: AddressSanitizer: heap-use-after-free /usr/include/c++/11/bits/atomic_base.h:488 in std::__atomic_base::load(std::memory_order) const Shadow bytes around the buggy address: 0x0c067fff8df0: fd fd fa fa fd fd fd fd fa fa fd fd fd fd fa fa 0x0c067fff8e00: fd fd fd fd fa fa fd fd fd fd fa fa fd fd fd fd 0x0c067fff8e10: fa fa fd fd fd fa fa fa fd fd fd fd fa fa fd fd 0x0c067fff8e20: fd fd fa fa fd fd fd fa fa fa fd fd fd fd fa fa 0x0c067fff8e30: fd fd fd fd fa fa fd fd fd fd fa fa 00 00 00 00 =>0x0c067fff8e40: fa fa fd fd[fd]fa fa fa fd fd fd fa fa fa fd fd 0x0c067fff8e50: fd fd fa fa fd fd fd fa fa fa 00 00 00 fa fa fa 0x0c067fff8e60: 00 00 00 fa fa fa fd fd fd fa fa fa 00 00 00 fa 0x0c067fff8e70: fa fa 00 00 00 fa fa fa fd fd fd fa fa fa 00 00 0x0c067fff8e80: 00 fa fa fa 00 00 00 fa fa fa fd fd fd fa fa fa 0x0c067fff8e90: 00 00 00 fa fa fa 00 00 00 fa fa fa fd fd fd fa Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb Shadow gap: cc ==2151==ABORTING ```

pereyra-m commented 3 months ago

Update

Changes due to review.

sebasfalcone commented 3 months ago

Issue blocked

This issue depends on https://github.com/wazuh/wazuh-http-request/issues/61

pereyra-m commented 2 months ago

Update

Rebase and unblock