Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-71527

Execution of EPrimBinary leaks memory when operation fails

    • Type: Icon: Task Task
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 6.3.0-rc0
    • Affects Version/s: None
    • Component/s: None
    • None
    • Fully Compatible
    • QO 2022-12-12, QO 2022-12-26

      Some SBE vm instructions may leak memory if instruction execution throws after operands have been popped from stack, but before the release is called.

      Example:

      When a division by zero occurs, the Instruction::div will throw without releasing popped operands.

      https://github.com/10gen/mongo/blob/master/src/mongo/db/exec/sbe/vm/vm.cpp#L5167

       

      As part of the fix, we should inspect other instructions and ensure that they also release the operands in case of execution error.

       

      Repro:

      TEST_F(SBEPrimBinaryTest, DivMemory) {
          auto& os = gctx->outStream();    auto expr = sbe::makeE<EPrimBinary>(
              EPrimBinary::Op::div,
              sbe::makeE<EPrimBinary>(EPrimBinary::Op::add,
                                      makeC(value::makeCopyDecimal(Decimal128(1))),
                                      makeC(value::makeCopyDecimal(Decimal128(1)))),
              sbe::makeE<EPrimBinary>(EPrimBinary::Op::sub,
                                      makeC(value::makeCopyDecimal(Decimal128(1))),
                                      makeC(value::makeCopyDecimal(Decimal128(1)))));
          printInputExpression(os, *expr);    auto compiledExpr = compileExpression(*expr);
          printCompiledExpression(os, *compiledExpr);    executeAndPrintVariation(os, *compiledExpr);
      }
      ==21950==ERROR: LeakSanitizer: detected memory leaksDirect leak of 16 byte(s) in 1 object(s) allocated from:
          #0 0x559c483bc262 in operator new[](unsigned long) /data/mci/7a061276a1aa147679600a512115c2c0/toolchain-builder/tmp/build-llvm.sh-UjE/llvm/projects/compiler-rt/lib/asan/asan_new_delete.cc:109:3
          #1 0x559c483d9262 in mongo::sbe::value::makeCopyDecimal(mongo::Decimal128 const&) /home/ubuntu/mongo/src/mongo/db/exec/sbe/values/value.h:1201:24
          #2 0x559c4e086fee in mongo::sbe::FastTuple<bool, mongo::sbe::value::TypeTags, unsigned long> mongo::sbe::value::genericArithmeticOp<mongo::sbe::value::Subtraction>(mongo::sbe::value::TypeTags, unsigned long, mongo::sbe::value::TypeTags, unsigned long) /home/ubuntu/mongo/src/mongo/db/exec/sbe/values/arith_common.cpp:152:35
          #3 0x559c4d33ef5d in mongo::sbe::vm::ByteCode::runInternal(mongo::sbe::vm::CodeFragment const*, long) /home/ubuntu/mongo/src/mongo/db/exec/sbe/vm/vm.cpp:5345:42
          #4 0x559c4d34d992 in mongo::sbe::vm::ByteCode::run(mongo::sbe::vm::CodeFragment const*) /home/ubuntu/mongo/src/mongo/db/exec/sbe/vm/vm.cpp:6406:9
          #5 0x559c484822d3 in mongo::sbe::EExpressionTestFixture::executeAndPrintVariation(std::ostream&, mongo::sbe::vm::CodeFragment const&) /home/ubuntu/mongo/src/mongo/db/exec/sbe/expression_test_base.h:133:42
          #6 0x559c48511f66 in mongo::sbe::UnitTest_SuiteNameSBEPrimBinaryTestTestNameDivMemory::_doTest() /home/ubuntu/mongo/src/mongo/db/exec/sbe/expressions/sbe_prim_binary_test.cpp:505:5
          #7 0x559c489f35bf in mongo::unittest::Test::run() /home/ubuntu/mongo/src/mongo/unittest/unittest.cpp:244:9
          #8 0x559c4842d0c6 in mongo::sbe::GoldenEExpressionTestFixture::run() /home/ubuntu/mongo/src/mongo/db/exec/sbe/expression_test_base.h:290:15
          #9 0x559c4853955b in mongo::unittest::Test::RegistrationAgent<mongo::sbe::UnitTest_SuiteNameSBEPrimBinaryTestTestNameDivMemory>::RegistrationAgent(mongo::unittest::TestInfo const*)::'lambda'()::operator()() const /home/ubuntu/mongo/src/mongo/unittest/framework.h:344:29
          #10 0x559c489f58ec in mongo::unittest::Suite::run(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int) /home/ubuntu/mongo/src/mongo/unittest/unittest.cpp:439:21
          #11 0x559c489f8735 in mongo::unittest::Suite::run(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int) /home/ubuntu/mongo/src/mongo/unittest/unittest.cpp:508:26
          #12 0x559c488433bf in main /home/ubuntu/mongo/src/mongo/unittest/unittest_main.cpp:132:19
          #13 0x7fdde6e29c86 in __libc_start_main /build/glibc-uZu3wS/glibc-2.27/csu/../csu/libc-start.c:310 

            Assignee:
            anna.wawrzyniak@mongodb.com Anna Wawrzyniak
            Reporter:
            anna.wawrzyniak@mongodb.com Anna Wawrzyniak
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: