[cfe-dev] static Matcher generate Use After Free
Maxim Ostapenko via cfe-dev
cfe-dev at lists.llvm.org
Thu Jun 8 05:14:19 PDT 2017
CC'ing Samuel, Alexey and Ilya.
On 06/06/17 12:55, Artem Dergachev wrote:
> Dunno. Crashes i've seen were random, so i'm not sure if being static
> is the only requirement.
Yeah, you are right, this is not enough. E.g. when I tried to make
several checkers static in NumberObjectConversionChecker.cpp nothing
changed (everything works fine).
However, when I've added following checker into
NumberObjectConversionChecker.cpp:
static auto varD =
expr(
hasDescendant(
declRefExpr(
hasDeclaration(
varDecl().bind("var")))));
I've actually got a use after free bug (ASan log is below). I'm not sure
how to fix this, but this is non-obvious even for experienced developers
that in some (non-obvious) cases static matchers don't work. IMHO this
is a bug that needs to be fixed upstream.
-Maxim
$ /home/maxim/src/build/upstream/build_asan/./bin/clang -cc1
-internal-isystem
/home/maxim/src/build/upstream/build_asan/lib/clang/5.0.0/include
-nostdsysteminc -analyze -analyzer-constraints=range
-analyzer-checker=osx,unix,core,alpha.security.taint -w -verify
/home/maxim/src/llvm-upstream/tools/clang/test/Analysis/redefined_system.c
=================================================================
==30739==ERROR: AddressSanitizer: heap-use-after-free on address
0x602000000eb8 at pc 0x00000848963e bp 0x7ffe83e19d10 sp 0x7ffe83e19d08
WRITE of size 4 at 0x602000000eb8 thread T0
#0 0x848963d in fetch_sub
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/atomic_base.h:624:16
#1 0x848963d in Release
/home/maxim/src/llvm-upstream/include/llvm/ADT/IntrusiveRefCntPtr.h:97
#2 0x848963d in release
/home/maxim/src/llvm-upstream/include/llvm/ADT/IntrusiveRefCntPtr.h:126
#3 0x848963d in release
/home/maxim/src/llvm-upstream/include/llvm/ADT/IntrusiveRefCntPtr.h:188
#4 0x848963d in ~IntrusiveRefCntPtr
/home/maxim/src/llvm-upstream/include/llvm/ADT/IntrusiveRefCntPtr.h:161
#5 0x848963d in ~IdDynMatcher
/home/maxim/src/llvm-upstream/tools/clang/lib/ASTMatchers/ASTMatchersInternal.cpp:74
#6 0x848963d in clang::ast_matchers::internal::(anonymous
namespace)::IdDynMatcher::~IdDynMatcher()
/home/maxim/src/llvm-upstream/tools/clang/lib/ASTMatchers/ASTMatchersInternal.cpp:74
#7 0x8173510 in Release
/home/maxim/src/llvm-upstream/include/llvm/ADT/IntrusiveRefCntPtr.h:100:7
#8 0x8173510 in release
/home/maxim/src/llvm-upstream/include/llvm/ADT/IntrusiveRefCntPtr.h:126
#9 0x8173510 in release
/home/maxim/src/llvm-upstream/include/llvm/ADT/IntrusiveRefCntPtr.h:188
#10 0x8173510 in ~IntrusiveRefCntPtr
/home/maxim/src/llvm-upstream/include/llvm/ADT/IntrusiveRefCntPtr.h:161
#11 0x8173510 in ~DynTypedMatcher
/home/maxim/src/llvm-upstream/tools/clang/include/clang/ASTMatchers/ASTMatchersInternal.h:315
#12 0x8173510 in ~WrapperMatcherInterface
/home/maxim/src/llvm-upstream/tools/clang/include/clang/ASTMatchers/ASTMatchersInternal.h:451
#13 0x8173510 in
clang::ast_matchers::internal::HasDeclarationMatcher<clang::DeclRefExpr,
clang::ast_matchers::internal::Matcher<clang::Decl>
>::~HasDeclarationMatcher()
/home/maxim/src/llvm-upstream/tools/clang/include/clang/ASTMatchers/ASTMatchersInternal.h:717
#14 0x8167c80 in Release
/home/maxim/src/llvm-upstream/include/llvm/ADT/IntrusiveRefCntPtr.h:100:7
#15 0x8167c80 in release
/home/maxim/src/llvm-upstream/include/llvm/ADT/IntrusiveRefCntPtr.h:126
#16 0x8167c80 in release
/home/maxim/src/llvm-upstream/include/llvm/ADT/IntrusiveRefCntPtr.h:188
#17 0x8167c80 in ~IntrusiveRefCntPtr
/home/maxim/src/llvm-upstream/include/llvm/ADT/IntrusiveRefCntPtr.h:161
#18 0x8167c80 in ~DynTypedMatcher
/home/maxim/src/llvm-upstream/tools/clang/include/clang/ASTMatchers/ASTMatchersInternal.h:315
#19 0x8167c80 in ~WrapperMatcherInterface
/home/maxim/src/llvm-upstream/tools/clang/include/clang/ASTMatchers/ASTMatchersInternal.h:451
#20 0x8167c80 in
clang::ast_matchers::internal::HasDescendantMatcher<clang::Expr,
clang::Stmt>::~HasDescendantMatcher()
/home/maxim/src/llvm-upstream/tools/clang/include/clang/ASTMatchers/ASTMatchersInternal.h:1319
#21 0x7fdda7b6f1a8 in __run_exit_handlers
/build/eglibc-MjiXCM/eglibc-2.19/stdlib/exit.c:82
#22 0x7fdda7b6f1f4 in exit
/build/eglibc-MjiXCM/eglibc-2.19/stdlib/exit.c:104
#23 0x7fdda7b54f4b in __libc_start_main
/build/eglibc-MjiXCM/eglibc-2.19/csu/libc-start.c:321
#24 0x8601fd in _start
(/home/maxim/src/build/upstream/build_asan/bin/clang-5.0+0x8601fd)
0x602000000eb8 is located 8 bytes inside of 16-byte region
[0x602000000eb0,0x602000000ec0)
freed by thread T0 here:
#0 0x96a520 in operator delete(void*)
/home/maxim/src/llvm-upstream/projects/compiler-rt/lib/asan/asan_new_delete.cc:126
#1 0x32c99ba in destroy
/home/maxim/src/llvm-upstream/lib/Support/ManagedStatic.cpp:75:3
#2 0x32c99ba in llvm::llvm_shutdown()
/home/maxim/src/llvm-upstream/lib/Support/ManagedStatic.cpp:87
#3 0x97452b in ~llvm_shutdown_obj
/home/maxim/src/llvm-upstream/include/llvm/Support/ManagedStatic.h:92:26
#4 0x97452b in main
/home/maxim/src/llvm-upstream/tools/clang/tools/driver/driver.cpp:512
#5 0x7fdda7b54f44 in __libc_start_main
/build/eglibc-MjiXCM/eglibc-2.19/csu/libc-start.c:287
previously allocated by thread T0 here:
#0 0x9697a0 in operator new(unsigned long)
/home/maxim/src/llvm-upstream/projects/compiler-rt/lib/asan/asan_new_delete.cc:82
#1 0x848bcdd in
llvm::object_creator<clang::ast_matchers::internal::(anonymous
namespace)::TrueMatcherImpl>::call()
/home/maxim/src/llvm-upstream/include/llvm/Support/ManagedStatic.h:24:32
#2 0x32c93c3 in
llvm::ManagedStaticBase::RegisterManagedStatic(void* (*)(), void
(*)(void*)) const
/home/maxim/src/llvm-upstream/lib/Support/ManagedStatic.cpp:45:19
#3 0x84823f0 in operator*
/home/maxim/src/llvm-upstream/include/llvm/Support/ManagedStatic.h:67:7
#4 0x84823f0 in
clang::ast_matchers::internal::DynTypedMatcher::trueMatcher(clang::ast_type_traits::ASTNodeKind)
/home/maxim/src/llvm-upstream/tools/clang/lib/ASTMatchers/ASTMatchersInternal.cpp:165
#5 0x816f4f8 in operator Matcher<clang::VarDecl>
/home/maxim/src/llvm-upstream/tools/clang/include/clang/ASTMatchers/ASTMatchersInternal.h:1145:12
#6 0x816f4f8 in
clang::ast_matchers::internal::BindableMatcher<clang::VarDecl>
clang::ast_matchers::internal::makeAllOfComposite<clang::VarDecl>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::VarDecl>
const*>)
/home/maxim/src/llvm-upstream/tools/clang/include/clang/ASTMatchers/ASTMatchersInternal.h:1282
#7 0x816f0b3 in
clang::ast_matchers::internal::BindableMatcher<clang::Decl>
clang::ast_matchers::internal::makeDynCastAllOfComposite<clang::Decl,
clang::VarDecl>(llvm::ArrayRef<clang::ast_matchers::internal::Matcher<clang::VarDecl>
const*>)
/home/maxim/src/llvm-upstream/tools/clang/include/clang/ASTMatchers/ASTMatchersInternal.h:1311:7
#8 0x813f3a2 in operator()
/home/maxim/src/llvm-upstream/tools/clang/include/clang/ASTMatchers/ASTMatchersInternal.h:72:39
#9 0x813f3a2 in (anonymous
namespace)::NumberObjectConversionChecker::checkASTCodeBody(clang::Decl
const*, clang::ento::AnalysisManager&, clang::ento::BugReporter&) const
/home/maxim/src/llvm-upstream/tools/clang/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp:341
#10 0x852fe39 in operator()
/home/maxim/src/llvm-upstream/tools/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h:59:12
#11 0x852fe39 in
clang::ento::CheckerManager::runCheckersOnASTBody(clang::Decl const*,
clang::ento::AnalysisManager&, clang::ento::BugReporter&)
/home/maxim/src/llvm-upstream/tools/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp:86
#12 0x60315c1 in (anonymous
namespace)::AnalysisConsumer::HandleCode(clang::Decl*, unsigned int,
clang::ento::ExprEngine::InliningModes, llvm::DenseSet<clang::Decl
const*, llvm::DenseMapInfo<clang::Decl const*> >*)
/home/maxim/src/llvm-upstream/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:683:17
#13 0x6020cb0 in clang::RecursiveASTVisitor<(anonymous
namespace)::AnalysisConsumer>::TraverseDecl(clang::Decl*)
/home/maxim/src/llvm-upstream/tools/clang/include/clang/AST/RecursiveASTVisitor.h
#14 0x601bebf in (anonymous
namespace)::AnalysisConsumer::HandleTranslationUnit(clang::ASTContext&)
/home/maxim/src/llvm-upstream/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:546:7
#15 0x60c31ab in clang::ParseAST(clang::Sema&, bool, bool)
/home/maxim/src/llvm-upstream/tools/clang/lib/Parse/ParseAST.cpp:159:13
#16 0x4515a7e in clang::FrontendAction::Execute()
/home/maxim/src/llvm-upstream/tools/clang/lib/Frontend/FrontendAction.cpp:856:8
#17 0x44221e0 in
clang::CompilerInstance::ExecuteAction(clang::FrontendAction&)
/home/maxim/src/llvm-upstream/tools/clang/lib/Frontend/CompilerInstance.cpp:970:11
#18 0x46f8cb1 in
clang::ExecuteCompilerInvocation(clang::CompilerInstance*)
/home/maxim/src/llvm-upstream/tools/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:249:25
#19 0x97b098 in cc1_main(llvm::ArrayRef<char const*>, char const*,
void*)
/home/maxim/src/llvm-upstream/tools/clang/tools/driver/cc1_main.cpp:221:13
#20 0x974865 in ExecuteCC1Tool
/home/maxim/src/llvm-upstream/tools/clang/tools/driver/driver.cpp:299:12
#21 0x974865 in main
/home/maxim/src/llvm-upstream/tools/clang/tools/driver/driver.cpp:380
#22 0x7fdda7b54f44 in __libc_start_main
/build/eglibc-MjiXCM/eglibc-2.19/csu/libc-start.c:287
SUMMARY: AddressSanitizer: heap-use-after-free
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/atomic_base.h:624:16
in fetch_sub
Shadow bytes around the buggy address:
0x0c047fff8180: fa fa fd fd fa fa fd fd fa fa fd fd fa fa fd fa
0x0c047fff8190: fa fa fd fa fa fa fd fd fa fa fd fd fa fa fd fa
0x0c047fff81a0: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
0x0c047fff81b0: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
0x0c047fff81c0: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fd
=>0x0c047fff81d0: fa fa fd fd fa fa fd[fd]fa fa fd fa fa fa fd fd
0x0c047fff81e0: fa fa fd fa fa fa fd fd fa fa fd fa fa fa fd fa
0x0c047fff81f0: fa fa fd fd fa fa fd fa fa fa fd fa fa fa fd fd
0x0c047fff8200: fa fa fd fa fa fa fd fd fa fa fd fa fa fa fd fa
0x0c047fff8210: fa fa fd fd fa fa fd fa fa fa fd fa fa fa fd fa
0x0c047fff8220: fa fa fd fd fa fa fd fa fa fa fd fd fa fa 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
==30739==ABORTING
>
> Also it seems to have been refactored out a few weeks ago, so there's
> no static matcher here anymore.
>
> 06/06/2017 12:45 PM, Maxim Ostapenko wrote:
>> On 06/06/17 12:41, Artem Dergachev via cfe-dev wrote:
>>> I think i've also noticed that static matcher objects don't work,
>>> but didn't pay enough attention to figure out why.
>>>
>>> In clang-tidy, as far as i understand, they don't use static
>>> matchers, but instead they have long-lived MatchFinder objects
>>> filled with all the matchers they need, so they don't need to
>>> construct the same matchers again and again. Maybe that'd be a
>>> viable approach in your case?
>>
>> Hm, but tools/extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp
>> actually has a static matcher:
>>
>> /// \brief Matcher that finds expressions that are candidates to be
>> wrapped with
>> /// 'std::move'.
>> ///
>> /// Binds the id \c AutoPtrOwnershipTransferId to the expression.
>> static StatementMatcher MovableArgumentMatcher =
>> expr(allOf(isLValue(), hasType(AutoPtrType)))
>> .bind(AutoPtrOwnershipTransferId);
>>
>> Or perhaps I'm missing something?
>>
>> -Maxim
>>
>>>
>>> 06/06/2017 12:15 PM, Aleksandr wrote:
>>>> Hello,
>>>>
>>>> I need help. I see, that using static Matcher generate error on
>>>> deallocated itself. For example, if we use:
>>>> static StatementMatcher MatcherA = callExpr();
>>>> MatcherA on dealloc tyrying to release reference counter of itself,
>>>> but reference counter was deleted by method llvm_shutdown, so it
>>>> use free memory.
>>>> Is it ok? We shouldn't use static matchers, or we have bug in
>>>> implementation in reference counter. What is it case?
>>>
>>> _______________________________________________
>>> cfe-dev mailing list
>>> cfe-dev at lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>>
>
More information about the cfe-dev
mailing list