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

AddressSanitizer issue in CBLFileLogger's apply method #2393

Closed
pasin opened this issue Mar 29, 2019 · 4 comments

Comments

@pasin
Copy link
Contributor

commented Mar 29, 2019

This can be reproduced when running Swift LogTest.testFileLoggingDefaultBinaryFormat() on Mac (not iOS).

==64407==ERROR: AddressSanitizer: stack-use-after-scope on address 0x0001046b08d8 at pc 0x00010012e6df bp 0x7ffeefbfc570 sp 0x7ffeefbfbd20
READ of size 64 at 0x0001046b08d8 thread T0
atos(64411,0x1000b75c0) malloc: enabling scribbling to detect mods to free blocks
2019-03-29 09:50:30.439478-0700 atos[64411:3576540] examining /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Xcode/Agents/xctest [64407]
    #0 0x10012e6de in __asan_memcpy (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x596de)
    #1 0x108a90d75 in std::__1::char_traits<char>::copy(char*, char const*, unsigned long) __string:225
    #2 0x108a94b2f in std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__init(char const*, unsigned long) string:1778
    #3 0x1095e9a24 in std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string(char const*, unsigned long) string:1799
    #4 0x1095e2bd4 in std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string(char const*, unsigned long) string:1797
    #5 0x1095e2ba5 in fleece::pure_slice::operator std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >() const slice.cc:238
    #6 0x108c4376b in fleece::pure_slice::asString() const slice.hh:117
    #7 0x108c5319b in c4log_writeToBinaryFile::$_0::operator()() const c4Base.cc:325
    #8 0x108c52fa4 in void fleece::function_ref<void ()>::callback_fn<c4log_writeToBinaryFile::$_0>(long) function_ref.hh:59
    #9 0x108b85dd3 in fleece::function_ref<void ()>::operator()() const function_ref.hh:72
    #10 0x108b85c2c in c4Internal::tryCatch(C4Error*, fleece::function_ref<void ()>) c4ExceptionUtils.cc:35
    #11 0x108c43a14 in c4log_writeToBinaryFile c4Base.cc:324
    #12 0x10895ac71 in -[CBLFileLogger apply] CBLFileLogger.mm:93
    #13 0x108959acc in -[CBLFileLogger setConfig:] CBLFileLogger.mm:57
    #14 0x108a3fa41 in FileLogger.config.didset FileLogger.swift:36
    #15 0x108a3ff64 in FileLogger.config.setter <compiler-generated>
    #16 0x10839ad9c in LogTest.testFileLoggingDefaultBinaryFormat() LogTest.swift:176
    #17 0x10839da1b in @objc LogTest.testFileLoggingDefaultBinaryFormat() <compiler-generated>
    #18 0x7fff2f28902b in __invoking___ (CoreFoundation:x86_64h+0x4a02b)
    #19 0x7fff2f288efe in -[NSInvocation invoke] (CoreFoundation:x86_64h+0x49efe)
    #20 0x10104f1fb in __24-[XCTestCase invokeTest]_block_invoke_2.197 (XCTest:x86_64+0x2d1fb)
    #21 0x1010d3d26 in -[XCTMemoryChecker _assertInvalidObjectsDeallocatedAfterScope:] (XCTest:x86_64+0xb1d26)
    #22 0x10105800f in -[XCTestCase assertInvalidObjectsDeallocatedAfterScope:] (XCTest:x86_64+0x3600f)
    #23 0x10104f18b in __24-[XCTestCase invokeTest]_block_invoke.191 (XCTest:x86_64+0x2d18b)
    #24 0x1010c1792 in -[XCTestCase(Failures) performFailableBlock:testCaseRun:shouldInterruptTest:] (XCTest:x86_64+0x9f792)
    #25 0x1010c16af in -[XCTestCase(Failures) _performTurningExceptionsIntoFailuresInterruptAfterHandling:block:] (XCTest:x86_64+0x9f6af)
    #26 0x10104eda4 in __24-[XCTestCase invokeTest]_block_invoke (XCTest:x86_64+0x2cda4)
    #27 0x1010c7b05 in -[XCUITestContext performInScope:] (XCTest:x86_64+0xa5b05)
    #28 0x10104e993 in -[XCTestCase testContextPerformInScope:] (XCTest:x86_64+0x2c993)
    #29 0x10104ea3f in -[XCTestCase invokeTest] (XCTest:x86_64+0x2ca3f)
    #30 0x1010505b1 in __26-[XCTestCase performTest:]_block_invoke_2 (XCTest:x86_64+0x2e5b1)
    #31 0x1010c1792 in -[XCTestCase(Failures) performFailableBlock:testCaseRun:shouldInterruptTest:] (XCTest:x86_64+0x9f792)
    #32 0x1010c16af in -[XCTestCase(Failures) _performTurningExceptionsIntoFailuresInterruptAfterHandling:block:] (XCTest:x86_64+0x9f6af)
    #33 0x1010504c8 in __26-[XCTestCase performTest:]_block_invoke.321 (XCTest:x86_64+0x2e4c8)
    #34 0x1010cffa1 in +[XCTContext runInContextForTestCase:block:] (XCTest:x86_64+0xadfa1)
    #35 0x10104fc3a in -[XCTestCase performTest:] (XCTest:x86_64+0x2dc3a)
    #36 0x1010a126e in -[XCTest runTest] (XCTest:x86_64+0x7f26e)
    #37 0x10104a73d in __27-[XCTestSuite performTest:]_block_invoke (XCTest:x86_64+0x2873d)
    #38 0x101049f19 in -[XCTestSuite _performProtectedSectionForTest:testSection:] (XCTest:x86_64+0x27f19)
    #39 0x10104a1d5 in -[XCTestSuite performTest:] (XCTest:x86_64+0x281d5)
    #40 0x1010a126e in -[XCTest runTest] (XCTest:x86_64+0x7f26e)
    #41 0x10104a73d in __27-[XCTestSuite performTest:]_block_invoke (XCTest:x86_64+0x2873d)
    #42 0x101049f19 in -[XCTestSuite _performProtectedSectionForTest:testSection:] (XCTest:x86_64+0x27f19)
    #43 0x10104a1d5 in -[XCTestSuite performTest:] (XCTest:x86_64+0x281d5)
    #44 0x1010a126e in -[XCTest runTest] (XCTest:x86_64+0x7f26e)
    #45 0x10104a73d in __27-[XCTestSuite performTest:]_block_invoke (XCTest:x86_64+0x2873d)
    #46 0x101049f19 in -[XCTestSuite _performProtectedSectionForTest:testSection:] (XCTest:x86_64+0x27f19)
    #47 0x10104a1d5 in -[XCTestSuite performTest:] (XCTest:x86_64+0x281d5)
    #48 0x1010a126e in -[XCTest runTest] (XCTest:x86_64+0x7f26e)
    #49 0x1010e4780 in __44-[XCTTestRunSession runTestsAndReturnError:]_block_invoke (XCTest:x86_64+0xc2780)
    #50 0x1010e484a in __44-[XCTTestRunSession runTestsAndReturnError:]_block_invoke.80 (XCTest:x86_64+0xc284a)
    #51 0x10106e99b in -[XCTestObservationCenter _observeTestExecutionForBlock:] (XCTest:x86_64+0x4c99b)
    #52 0x1010e4536 in -[XCTTestRunSession runTestsAndReturnError:] (XCTest:x86_64+0xc2536)
    #53 0x10102df45 in -[XCTestDriver runTestsAndReturnError:] (XCTest:x86_64+0xbf45)
    #54 0x1010cc23f in _XCTestMain (XCTest:x86_64+0xaa23f)
    #55 0x100002103 in main (xctest:x86_64+0x100002103)
    #56 0x7fff5b6f23d4 in start (libdyld.dylib:x86_64+0x163d4)

Address 0x0001046b08d8 is located in stack of thread T0 at offset 216 in frame
    #0 0x108959d7f in -[CBLFileLogger apply] CBLFileLogger.mm:70

  This frame has 8 object(s):
    [32, 40) 'error' (line 71)
    [64, 72) 'icr.temp'
    [96, 152) 'options' (line 83)
    [192, 280) 'ref.tmp' (line 83) <== Memory access at offset 216 is inside this variable
    [320, 408) 'ref.tmp47' (line 83)
    [448, 460) 'c4err' (line 92)
    [480, 536) 'agg.tmp'
    [576, 584) 'icr.temp62'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-use-after-scope (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x596de) in __asan_memcpy
Shadow bytes around the buggy address:
  0x1000208d60c0: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x1000208d60d0: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x1000208d60e0: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x1000208d60f0: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x1000208d6100: f1 f1 f1 f1 00 f2 f2 f2 00 f2 f2 f2 00 00 00 00
=>0x1000208d6110: 00 00 00 f2 f2 f2 f2 f2 f8 f8 f8[f8]f8 f8 f8 f8
  0x1000208d6120: f8 f8 f8 f2 f2 f2 f2 f2 f8 f8 f8 f8 f8 f8 f8 f8
  0x1000208d6130: f8 f8 f8 f2 f2 f2 f2 f2 00 04 f2 f2 00 00 00 00
  0x1000208d6140: 00 00 00 f2 f2 f2 f2 f2 00 f3 f3 f3 00 00 00 00
  0x1000208d6150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x1000208d6160: 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
  Shadow gap:              cc
2019-03-29 09:50:32.167825-0700 xctest[64407:3576485] =================================================================
@pasin

This comment has been minimized.

Copy link
Contributor Author

commented Mar 29, 2019

From the code, I don't see issue as Slice.asString() accessed to a memory pointer which is alive in the calling scope. As expected, the issue is gone if commented this part in CBLStringBytes out.

@pasin pasin added this to the Iridium milestone Mar 29, 2019

@pasin

This comment has been minimized.

Copy link
Contributor Author

commented Mar 29, 2019

@snej @borrrden Any ideas to rewrite this part to avoid this issue?

@pasin

This comment has been minimized.

Copy link
Contributor Author

commented Mar 29, 2019

I was able to get around with it by defining CBLStringBytes dir(_config.directory); outside of { } struct initializer.

@pasin pasin closed this Mar 29, 2019

@pasin pasin added the bug label Mar 29, 2019

@pasin pasin changed the title AddressSanitizer issue in c4log_writeToBinaryFile() AddressSanitizer issue in CBLFileLogger's apply method Mar 29, 2019

pasin added a commit that referenced this issue Mar 29, 2019

Fix AddressSanitizer issue in CBLFileLogger’s apply method
* Created CBLStringBytes directory outside C4LogFileOptions’s initializer scope.

#2393

pasin added a commit that referenced this issue Mar 29, 2019

Fix AddressSanitizer issue in CBLFileLogger’s apply method
* Created CBLStringBytes directory outside C4LogFileOptions’s initializer scope.

#2393
@snej

This comment has been minimized.

Copy link
Member

commented Mar 29, 2019

The reason for the crash is that the CBLStringBytes object is scoped to the declaration expression that contains it. After options is constructed, the object exits scope and is destructed, and with it goes the storage for the slice that was assigned to base_path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.