From e5551afadaff66198f5a7faa594fb8df84a1c339 Mon Sep 17 00:00:00 2001 From: Damian Wrobel Date: Tue, 6 Mar 2018 22:19:40 +0100 Subject: [PATCH] AddressSanitizer: fix heap-use-after-free in downloadedDataTest() (#898) We had to remove this test: void downloadedDataTest() { rtFileCache::instance()->clearCache(); addDataToCache("http://fileserver/file.jpeg",getHeader(),getBodyData(),fixedData.length()); rtFileDownloadRequest* request = new rtFileDownloadRequest("http://fileserver/file.jpeg",this); expectedStatusCode = 0; expectedCachePresence = true; expectedHttpCode = 200; (1) rtFileDownloader::instance()->downloadFile(request); char *data = new char [1000]; size_t size = 0; memset (data, 0, 1000); (2) request->downloadedData(data, size); //since the data would have been consumed by callback EXPECT_TRUE (size == 0); delete[] data; sem_wait(testSem); } Because it is not possible to invoke (2) after (1) has finished ('request' is being deleted in the end of downloadFile() method). This is where it crashes: ==30599==ERROR: AddressSanitizer: heap-use-after-free on address 0x614000075878 at pc 0x000000825a05 bp 0x7ffe924a7a60 sp 0x7ffe924a7a50 READ of size 8 at 0x614000075878 thread T0 #0 0x825a04 in rtFileDownloadRequest::downloadedData(char*&, unsigned long&) pxCore/src/rtFileDownloader.cpp:265 #1 0x6692e1 in rtFileDownloaderTest::downloadedDataTest() pxCore/tests/pxScene2d/test_imagecache.cpp:1020 #2 0x64ddcb in rtFileDownloaderTest_checkCacheTests_Test::TestBody() pxCore/tests/pxScene2d/test_imagecache.cpp:1245 #3 0x7ad316 in void testing::internal::HandleSehExceptionsInMethodIfSupported(testing::Test*, void (testing::Test::*)(), char const*) (pxCore/tests/pxScene2d/pxscene2dtests+0x7ad316) #4 0x7a09d6 in void testing::internal::HandleExceptionsInMethodIfSupported(testing::Test*, void (testing::Test::*)(), char const*) pxCore/tests/pxScene2d/../../examples/pxScene2d/external/gtest/googletest/src/gtest.cc:2438 #5 0x75d56b in testing::Test::Run() pxCore/tests/pxScene2d/../../examples/pxScene2d/external/gtest/googletest/src/gtest.cc:2474 #6 0x75e857 in testing::TestInfo::Run() pxCore/tests/pxScene2d/../../examples/pxScene2d/external/gtest/googletest/src/gtest.cc:2656 #7 0x75f3d0 in testing::TestCase::Run() pxCore/tests/pxScene2d/../../examples/pxScene2d/external/gtest/googletest/src/gtest.cc:2774 #8 0x76ff6e in testing::internal::UnitTestImpl::RunAllTests() pxCore/tests/pxScene2d/../../examples/pxScene2d/external/gtest/googletest/src/gtest.cc:4649 #9 0x7afd55 in bool testing::internal::HandleSehExceptionsInMethodIfSupported(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) pxCore/tests/pxScene2d/../../examples/pxScene2d/external/gtest/googletest/src/gtest.cc:2402 #10 0x7a2b35 in bool testing::internal::HandleExceptionsInMethodIfSupported(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) (pxCore/tests/pxScene2d/pxscene2dtests+0x7a2b35) #11 0x76d177 in testing::UnitTest::Run() pxCore/tests/pxScene2d/../../examples/pxScene2d/external/gtest/googletest/src/gtest.cc:4257 #12 0x5299db in RUN_ALL_TESTS() (pxCore/tests/pxScene2d/pxscene2dtests+0x5299db) #13 0x5295c7 in main pxCore/tests/pxScene2d/pxscene2dtestsmain.cpp:101 #14 0x7f3562c8d009 in __libc_start_main (/lib64/libc.so.6+0x21009) #15 0x5293c9 in _start (pxCore/tests/pxScene2d/pxscene2dtests+0x5293c9) 0x614000075878 is located 56 bytes inside of 448-byte region [0x614000075840,0x614000075a00) freed by thread T0 here: #0 0x7f3568a5cfd0 in operator delete(void*) (/lib64/libasan.so.4+0xe0fd0) #1 0x827368 in rtFileDownloader::downloadFile(rtFileDownloadRequest*) pxCore/src/rtFileDownloader.cpp:630 #2 0x669241 in rtFileDownloaderTest::downloadedDataTest() pxCore/tests/pxScene2d/test_imagecache.cpp:1016 #3 0x64ddcb in rtFileDownloaderTest_checkCacheTests_Test::TestBody() pxCore/tests/pxScene2d/test_imagecache.cpp:1245 #4 0x7ad316 in void testing::internal::HandleSehExceptionsInMethodIfSupported(testing::Test*, void (testing::Test::*)(), char const*) (pxCore/tests/pxScene2d/pxscene2dtests+0x7ad316) #5 0x7a09d6 in void testing::internal::HandleExceptionsInMethodIfSupported(testing::Test*, void (testing::Test::*)(), char const*) pxCore/tests/pxScene2d/../../examples/pxScene2d/external/gtest/googletest/src/gtest.cc:2438 #6 0x75d56b in testing::Test::Run() pxCore/tests/pxScene2d/../../examples/pxScene2d/external/gtest/googletest/src/gtest.cc:2474 #7 0x75e857 in testing::TestInfo::Run() pxCore/tests/pxScene2d/../../examples/pxScene2d/external/gtest/googletest/src/gtest.cc:2656 #8 0x75f3d0 in testing::TestCase::Run() pxCore/tests/pxScene2d/../../examples/pxScene2d/external/gtest/googletest/src/gtest.cc:2774 #9 0x76ff6e in testing::internal::UnitTestImpl::RunAllTests() pxCore/tests/pxScene2d/../../examples/pxScene2d/external/gtest/googletest/src/gtest.cc:4649 #10 0x7afd55 in bool testing::internal::HandleSehExceptionsInMethodIfSupported(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) pxCore/tests/pxScene2d/../../examples/pxScene2d/external/gtest/googletest/src/gtest.cc:2402 #11 0x7a2b35 in bool testing::internal::HandleExceptionsInMethodIfSupported(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) (pxCore/tests/pxScene2d/pxscene2dtests+0x7a2b35) #12 0x76d177 in testing::UnitTest::Run() pxCore/tests/pxScene2d/../../examples/pxScene2d/external/gtest/googletest/src/gtest.cc:4257 #13 0x5299db in RUN_ALL_TESTS() (pxCore/tests/pxScene2d/pxscene2dtests+0x5299db) #14 0x5295c7 in main pxCore/tests/pxScene2d/pxscene2dtestsmain.cpp:101 #15 0x7f3562c8d009 in __libc_start_main (/lib64/libc.so.6+0x21009) previously allocated by thread T0 here: #0 0x7f3568a5c158 in operator new(unsigned long) (/lib64/libasan.so.4+0xe0158) #1 0x669124 in rtFileDownloaderTest::downloadedDataTest() pxCore/tests/pxScene2d/test_imagecache.cpp:1012 #2 0x64ddcb in rtFileDownloaderTest_checkCacheTests_Test::TestBody() pxCore/tests/pxScene2d/test_imagecache.cpp:1245 #3 0x7ad316 in void testing::internal::HandleSehExceptionsInMethodIfSupported(testing::Test*, void (testing::Test::*)(), char const*) (pxCore/tests/pxScene2d/pxscene2dtests+0x7ad316) #4 0x7a09d6 in void testing::internal::HandleExceptionsInMethodIfSupported(testing::Test*, void (testing::Test::*)(), char const*) pxCore/tests/pxScene2d/../../examples/pxScene2d/external/gtest/googletest/src/gtest.cc:2438 #5 0x75d56b in testing::Test::Run() pxCore/tests/pxScene2d/../../examples/pxScene2d/external/gtest/googletest/src/gtest.cc:2474 #6 0x75e857 in testing::TestInfo::Run() pxCore/tests/pxScene2d/../../examples/pxScene2d/external/gtest/googletest/src/gtest.cc:2656 #7 0x75f3d0 in testing::TestCase::Run() pxCore/tests/pxScene2d/../../examples/pxScene2d/external/gtest/googletest/src/gtest.cc:2774 #8 0x76ff6e in testing::internal::UnitTestImpl::RunAllTests() pxCore/tests/pxScene2d/../../examples/pxScene2d/external/gtest/googletest/src/gtest.cc:4649 #9 0x7afd55 in bool testing::internal::HandleSehExceptionsInMethodIfSupported(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) pxCore/tests/pxScene2d/../../examples/pxScene2d/external/gtest/googletest/src/gtest.cc:2402 #10 0x7a2b35 in bool testing::internal::HandleExceptionsInMethodIfSupported(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) (pxCore/tests/pxScene2d/pxscene2dtests+0x7a2b35) #11 0x76d177 in testing::UnitTest::Run() pxCore/tests/pxScene2d/../../examples/pxScene2d/external/gtest/googletest/src/gtest.cc:4257 #12 0x5299db in RUN_ALL_TESTS() (pxCore/tests/pxScene2d/pxscene2dtests+0x5299db) #13 0x5295c7 in main pxCore/tests/pxScene2d/pxscene2dtestsmain.cpp:101 #14 0x7f3562c8d009 in __libc_start_main (/lib64/libc.so.6+0x21009) SUMMARY: AddressSanitizer: heap-use-after-free pxCore/src/rtFileDownloader.cpp:265 in rtFileDownloadRequest::downloadedData(char*&, unsigned long&) Shadow bytes around the buggy address: 0x0c2880006ab0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c2880006ac0: fa fa fa fa fa fa fa fa fa fa fa fa ^[1mfa fa fa fa 0x0c2880006ad0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c2880006ae0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c2880006af0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa =>0x0c2880006b00: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd[fd] 0x0c2880006b10: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x0c2880006b20: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x0c2880006b30: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x0c2880006b40: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00 0x0c2880006b50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 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 ==30599==ABORTING --- tests/pxScene2d/test_imagecache.cpp | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/tests/pxScene2d/test_imagecache.cpp b/tests/pxScene2d/test_imagecache.cpp index 253e3d5e84..3ac157f8ee 100644 --- a/tests/pxScene2d/test_imagecache.cpp +++ b/tests/pxScene2d/test_imagecache.cpp @@ -1024,25 +1024,6 @@ class rtFileDownloaderTest : public testing::Test, public commonTestFns EXPECT_TRUE (request->downloadHandleExpiresTime() == 3); } - void downloadedDataTest() - { - rtFileCache::instance()->clearCache(); - addDataToCache("http://fileserver/file.jpeg",getHeader(),getBodyData(),fixedData.length()); - rtFileDownloadRequest* request = new rtFileDownloadRequest("http://fileserver/file.jpeg",this); - expectedStatusCode = 0; - expectedCachePresence = true; - expectedHttpCode = 200; - rtFileDownloader::instance()->downloadFile(request); - char *data = new char [1000]; - size_t size = 0; - memset (data, 0, 1000); - request->downloadedData(data, size); - //since the data would have been consumed by callback - EXPECT_TRUE (size == 0); - delete[] data; - sem_wait(testSem); - } - void addToDownloadQueueTest() { rtFileCache::instance()->clearCache(); @@ -1261,7 +1242,6 @@ TEST_F(rtFileDownloaderTest, checkCacheTests) setCallbackFunctionNullTest(); setCallbackDataTest(); setDownloadHandleExpiresTimeTest(); - downloadedDataTest(); addToDownloadQueueTest(); setCallbackFunctionNullInDownloadFileTest(); setDefaultCallbackFunctionNullTest();