From 27049cc1da941044143ed7a185fe451edf23fffa Mon Sep 17 00:00:00 2001 From: Brian Neradt Date: Fri, 7 Jun 2024 20:06:49 +0000 Subject: [PATCH] txn_box: Address use after free in Do_upstream_rsp_body ASan reported a use-after-free in Do_upstream_rsp_body. This adds clearing the Continuation's data of the State member upon destruction because any use of it will be a use after free by definition. ``` ================================================================= ==764533==ERROR: AddressSanitizer: heap-use-after-free on address 0x62d006090610 at pc 0x7f5702f4d0d2 bp 0x7f5833a15ca0 sp 0x7f5833a15c90 READ of size 8 at 0x62d006090610 thread T24 ([ET_NET 22]) #0 0x7f5702f4d0d1 in operator() /sd/workspace/src/git.ouryahoo.com/Edge/build/_scm/trafficserver10.0_asan/plugins/experimental/txn_box/plugin/src/Machinery.cc:2579 #1 0x7f5702f4d0d1 in _FUN /sd/workspace/src/git.ouryahoo.com/Edge/build/_scm/trafficserver10.0_asan/plugins/experimental/txn_box/plugin/src/Machinery.cc:2591 #2 0x1251b2a in INKContInternal::handle_event(int, void*) /sd/workspace/src/git.ouryahoo.com/Edge/build/_scm/trafficserver10.0_asan/src/api/InkContInternal.cc:153 #3 0x116b304 in Continuation::handleEvent(int, void*) /sd/workspace/src/git.ouryahoo.com/Edge/build/_scm/trafficserver10.0_asan/include/iocore/eventsystem/Continuation.h:228 #4 0x116b304 in Continuation::handleEvent(int, void*) /sd/workspace/src/git.ouryahoo.com/Edge/build/_scm/trafficserver10.0_asan/include/iocore/eventsystem/Continuation.h:224 #5 0x116b304 in EThread::process_event(Event*, int) /sd/workspace/src/git.ouryahoo.com/Edge/build/_scm/trafficserver10.0_asan/src/iocore/eventsystem/UnixEThread.cc:162 #6 0x116d132 in EThread::process_queue(Queue*, int*, int*) /sd/workspace/src/git.ouryahoo.com/Edge/build/_scm/trafficserver10.0_asan/src/iocore/eventsystem/UnixEThread.cc:197 #7 0x116e07f in EThread::execute_regular() /sd/workspace/src/git.ouryahoo.com/Edge/build/_scm/trafficserver10.0_asan/src/iocore/eventsystem/UnixEThread.cc:255 #8 0x116f7d8 in EThread::execute() /sd/workspace/src/git.ouryahoo.com/Edge/build/_scm/trafficserver10.0_asan/src/iocore/eventsystem/UnixEThread.cc:348 #9 0x116f7d8 in EThread::execute() /sd/workspace/src/git.ouryahoo.com/Edge/build/_scm/trafficserver10.0_asan/src/iocore/eventsystem/UnixEThread.cc:326 #10 0x11684e7 in spawn_thread_internal /sd/workspace/src/git.ouryahoo.com/Edge/build/_scm/trafficserver10.0_asan/src/iocore/eventsystem/Thread.cc:75 #11 0x7f58493031c9 in start_thread (/lib64/libpthread.so.0+0x81c9) (BuildId: e08f397aa6b7de799209cd5bc35aabe0496678f1) #12 0x7f5848f6fe72 in __clone (/lib64/libc.so.6+0x39e72) (BuildId: 574d156ec0c828321a4038189fc1cfe74d0bb2ec) 0x62d006090610 is located 528 bytes inside of 32752-byte region [0x62d006090400,0x62d0060983f0) freed by thread T24 ([ET_NET 22]) here: #0 0x7f584aa05170 in __interceptor_free.part.0 (/lib64/libasan.so.8+0xdc170) (BuildId: 71dbf393857c775be459ab5583ba7b5fcbd9c884) #1 0x7f5849b71665 in swoc::_1_5_12::MemArena::Block::operator delete(void*) _sdk/release_posix-x86_64_gcc_12/libswoc_1.5.12/include/swoc/MemArena.h:646 #2 0x7f5849b71665 in swoc::_1_5_12::MemArena::~MemArena() _scm/libswoc/code/src/MemArena.cc:276 previously allocated by thread T24 ([ET_NET 22]) here: #0 0x7f584aa0662f in malloc (/lib64/libasan.so.8+0xdd62f) (BuildId: 71dbf393857c775be459ab5583ba7b5fcbd9c884) #1 0x7f5849b718ab in swoc::_1_5_12::MemArena::make_block(unsigned long) _scm/libswoc/code/src/MemArena.cc:99 Thread T24 ([ET_NET 22]) created by T0 ([TS_MAIN]) here: #0 0x7f584a971ea5 in __interceptor_pthread_create (/lib64/libasan.so.8+0x48ea5) (BuildId: 71dbf393857c775be459ab5583ba7b5fcbd9c884) #1 0x1168c0c in ink_thread_create /sd/workspace/src/git.ouryahoo.com/Edge/build/_scm/trafficserver10.0_asan/include/tscore/ink_thread.h:129 #2 0x1168c0c in Thread::start(char const*, void*, unsigned long, std::function const&) /sd/workspace/src/git.ouryahoo.com/Edge/build/_scm/trafficserver10.0_asan/src/iocore/eventsystem/Thread.cc:92 #3 0x117a904 in EventProcessor::spawn_event_threads(int, int, unsigned long) /sd/workspace/src/git.ouryahoo.com/Edge/build/_scm/trafficserver10.0_asan/src/iocore/eventsystem/UnixEventProcessor.cc:467 #4 0x117b75a in EventProcessor::start(int, unsigned long) /sd/workspace/src/git.ouryahoo.com/Edge/build/_scm/trafficserver10.0_asan/src/iocore/eventsystem/UnixEventProcessor.cc:548 #5 0x56dc74 in main /sd/workspace/src/git.ouryahoo.com/Edge/build/_scm/trafficserver10.0_asan/src/traffic_server/traffic_server.cc:2104 #6 0x7f5848f70d84 in __libc_start_main (/lib64/libc.so.6+0x3ad84) (BuildId: 574d156ec0c828321a4038189fc1cfe74d0bb2ec) SUMMARY: AddressSanitizer: heap-use-after-free /sd/workspace/src/git.ouryahoo.com/Edge/build/_scm/trafficserver10.0_asan/plugins/experimental/txn_box/plugin/src/Machinery.cc:2579 in operator() Shadow bytes around the buggy address: 0x62d006090380: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x62d006090400: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x62d006090480: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x62d006090500: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x62d006090580: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd =>0x62d006090600: fd fd[fd]fd fd fd fd fd fd fd fd fd fd fd fd fd 0x62d006090680: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x62d006090700: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x62d006090780: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x62d006090800: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x62d006090880: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 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 ==764533==ABORTING ``` --- plugins/experimental/txn_box/plugin/src/Machinery.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plugins/experimental/txn_box/plugin/src/Machinery.cc b/plugins/experimental/txn_box/plugin/src/Machinery.cc index 7685f6a241d..758173c4998 100644 --- a/plugins/experimental/txn_box/plugin/src/Machinery.cc +++ b/plugins/experimental/txn_box/plugin/src/Machinery.cc @@ -2538,9 +2538,13 @@ Do_upstream_rsp_body::invoke(Context &ctx) struct State { TextView _view; ///< Source view for body. TSIOBuffer _tsio_buff = nullptr; ///< Buffer used to write body. + TSCont _cont = nullptr; ///< Transform continuation with which State is associated. /// Clean up the @c IOBuffer. ~State() { + if (_cont != nullptr) { + TSContDataSet(_cont, nullptr); + } if (_tsio_buff) { TSIOBufferDestroy(_tsio_buff); } @@ -2550,6 +2554,10 @@ Do_upstream_rsp_body::invoke(Context &ctx) auto static transform = [](TSCont contp, TSEvent ev_code, void *) -> int { if (TSVConnClosedGet(contp)) { // IOBuffer is cleaned up at transaction close, not here. + if (auto state = static_cast(TSContDataGet(contp)); state) { + state->_cont = nullptr; + TSContDataSet(contp, nullptr); + } TSContDestroy(contp); return 0; } @@ -2614,6 +2622,7 @@ Do_upstream_rsp_body::invoke(Context &ctx) auto state = ctx.make(); ctx.mark_for_cleanup(state); auto cont = TSTransformCreate(transform, ctx._txn); + state->_cont = cont; state->_view = *content; TSContDataSet(cont, state); TSHttpTxnHookAdd(ctx._txn, TS_HTTP_RESPONSE_TRANSFORM_HOOK, cont);