Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

yamlcpp: use after free #3561

Closed
mpranj opened this issue Nov 15, 2020 · 2 comments
Closed

yamlcpp: use after free #3561

mpranj opened this issue Nov 15, 2020 · 2 comments
Assignees
Milestone

Comments

@mpranj
Copy link
Member

mpranj commented Nov 15, 2020

ASAN found a heap-use-after-free problem in yamlcpp. Tested on master revision: f370cc5 on cirrus.
I suspect clang/ASAN was updated so now we see this.

@sanssecours can you take a look?

 90/202 Test #129: testmod_yamlcpp ...............................Child aborted***Exception:   1.46 sec
[==========] Running 4 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 4 tests from yamlcpp
[ RUN      ] yamlcpp.contract
[       OK ] yamlcpp.contract (3 ms)
[ RUN      ] yamlcpp.flat
=================================================================
==13595==ERROR: AddressSanitizer: heap-use-after-free on address 0x606000002678 at pc 0x00010cb97faa bp 0x7ffee3494250 sp 0x7ffee3494248
WRITE of size 8 at 0x606000002678 thread T0
    #0 0x10cb97fa9 in ksRewind keyset.c:1340
    #1 0x10cb99975 in ksClose keyset.c:2554
    #2 0x10cb9914b in ksDel keyset.c:443
    #3 0x10c7c5ffb in test_read(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, kdb::KeySet, int) testmod_yamlcpp.cpp:71
    #4 0x10c7c4b42 in yamlcpp_flat_Test::TestBody() testmod_yamlcpp.cpp:100
    #5 0x10c7efeca in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) gtest.cc:2469
    #6 0x10c7ef9af in testing::Test::Run() gtest.cc:2508
    #7 0x10c7f2dc1 in testing::TestInfo::Run() gtest.cc:2684
    #8 0x10c7f6789 in testing::TestSuite::Run() gtest.cc:2816
    #9 0x10c816c27 in testing::internal::UnitTestImpl::RunAllTests() gtest.cc:5338
    #10 0x10c815889 in bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) gtest.cc:2469
    #11 0x10c8153b5 in testing::UnitTest::Run() gtest.cc:4925
    #12 0x10c7c8c4c in main testmod_yamlcpp.cpp:160
    #13 0x7fff71d48cc8 in start+0x0 (libdyld.dylib:x86_64+0x1acc8)

0x606000002678 is located 24 bytes inside of 64-byte region [0x606000002660,0x6060000026a0)
freed by thread T0 here:
    #0 0x10cd13549 in wrap_free+0xa9 (libclang_rt.asan_osx_dynamic.dylib:x86_64+0x46549)
    #1 0x10cb99239 in ksDel keyset.c:459
    #2 0x110ae43df in elektraYamlcppGet yamlcpp.cpp:117
    #3 0x10c7c541f in test_read(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, kdb::KeySet, int) testmod_yamlcpp.cpp:67
    #4 0x10c7c4b42 in yamlcpp_flat_Test::TestBody() testmod_yamlcpp.cpp:100
    #5 0x10c7efeca in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) gtest.cc:2469
    #6 0x10c7ef9af in testing::Test::Run() gtest.cc:2508
    #7 0x10c7f2dc1 in testing::TestInfo::Run() gtest.cc:2684
    #8 0x10c7f6789 in testing::TestSuite::Run() gtest.cc:2816
    #9 0x10c816c27 in testing::internal::UnitTestImpl::RunAllTests() gtest.cc:5338
    #10 0x10c815889 in bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) gtest.cc:2469
    #11 0x10c8153b5 in testing::UnitTest::Run() gtest.cc:4925
    #12 0x10c7c8c4c in main testmod_yamlcpp.cpp:160
    #13 0x7fff71d48cc8 in start+0x0 (libdyld.dylib:x86_64+0x1acc8)

previously allocated by thread T0 here:
    #0 0x10cd13400 in wrap_malloc+0xa0 (libclang_rt.asan_osx_dynamic.dylib:x86_64+0x46400)
    #1 0x10cb877e2 in elektraMalloc internal.c:275
    #2 0x10cb96141 in ksVNew keyset.c:249
    #3 0x10cb960ae in ksNew keyset.c:231
    #4 0x10c7c535c in test_read(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, kdb::KeySet, int) testmod_yamlcpp.cpp:66
    #5 0x10c7c4b42 in yamlcpp_flat_Test::TestBody() testmod_yamlcpp.cpp:100
    #6 0x10c7efeca in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) gtest.cc:2469
    #7 0x10c7ef9af in testing::Test::Run() gtest.cc:2508
    #8 0x10c7f2dc1 in testing::TestInfo::Run() gtest.cc:2684
    #9 0x10c7f6789 in testing::TestSuite::Run() gtest.cc:2816
    #10 0x10c816c27 in testing::internal::UnitTestImpl::RunAllTests() gtest.cc:5338
    #11 0x10c815889 in bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) gtest.cc:2469
    #12 0x10c8153b5 in testing::UnitTest::Run() gtest.cc:4925
    #13 0x10c7c8c4c in main testmod_yamlcpp.cpp:160
    #14 0x7fff71d48cc8 in start+0x0 (libdyld.dylib:x86_64+0x1acc8)

SUMMARY: AddressSanitizer: heap-use-after-free keyset.c:1340 in ksRewind
Shadow bytes around the buggy address:
  0x1c0c00000470: 00 00 00 00 fa fa fa fa 00 00 00 00 00 00 00 06
  0x1c0c00000480: fa fa fa fa fd fd fd fd fd fd fd fd fa fa fa fa
  0x1c0c00000490: fd fd fd fd fd fd fd fd fa fa fa fa fd fd fd fd
  0x1c0c000004a0: fd fd fd fd fa fa fa fa 00 00 00 00 00 00 00 00
  0x1c0c000004b0: fa fa fa fa 00 00 00 00 00 00 00 00 fa fa fa fa
=>0x1c0c000004c0: fd fd fd fd fd fd fd fd fa fa fa fa fd fd fd[fd]
  0x1c0c000004d0: fd fd fd fd fa fa fa fa fd fd fd fd fd fd fd fd
  0x1c0c000004e0: fa fa fa fa 00 00 00 00 00 00 00 00 fa fa fa fa
  0x1c0c000004f0: 00 00 00 00 00 00 00 00 fa fa fa fa 00 00 00 00
  0x1c0c00000500: 00 00 00 00 fa fa fa fa fd fd fd fd fd fd fd fd
  0x1c0c00000510: fa fa fa fa 00 00 00 00 00 00 00 00 fa fa fa 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
==13595==ABORTING
@mpranj mpranj added this to the 0.9.4 milestone Nov 15, 2020
@sanssecours
Copy link
Member

Thank you for the bug report. The problem seems to be located somewhere here:

try
{
key.set<bool> (node.as<bool> ());
key.setMeta ("type", "boolean");
}
catch (YAML::BadConversion const &)
{
key.set<string> (node.as<string> ()); // Save value as string, if `node` is a quoted scalar
}

The “use after free” occurs, when the conversion to boolean – via node.as<bool> () – fails. Currently I do not know why that is the case though.

@mpranj
Copy link
Member Author

mpranj commented Nov 24, 2020

Seems that this (at least) fails on builds with homebrew's clang/llvm 11.0.0.
The tests run fine with Apple's current Xcode/clang 12.0.0.12000032.

I disabled the yamlcpp plugin for the affected builds in 5d515ac, which should be reverted when a fix is available.

sanssecours added a commit to sanssecours/elektra that referenced this issue Nov 24, 2020
sanssecours added a commit to sanssecours/elektra that referenced this issue Nov 24, 2020
@mpranj mpranj closed this as completed in 7da378d Nov 28, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants