[PATCH] [analyzer] Detect use-after-free scenarios in -dealloc after calling [super dealloc]

Richard Smith richard at metafoo.co.uk
Sun Aug 24 22:40:18 PDT 2014


On Sat, Aug 23, 2014 at 11:17 PM, David Kilzer <ddkilzer at kilzer.net> wrote:

> > * Crash in ASTMatchers running `test/Analysis/PR2978.m` test, possibly
> due to invalid code in `-dealloc` method. Haven't figured out how to make a
> stand-alone test case yet.
>
> Something is going horribly wrong dereferencing a `clang::Stmt *` into a
> `const clang::Stmt &` in this call:
>
>   Finder.match(*S, Ctx);
>
> Changing the pointer type to `const clang::Stmt *` as passed into the
> method had no effect.  I also tried this to no avail:
>
>   const Stmt &SRef = *S;
>   Finder.match(SRef, Ctx);
>
> Here's an lldb session showing the badness.  I know something is going
> wrong because the value of `Node.Aligner` in the `match()` method is the
> same value as the `S` pointer (`0x000000010a033ce0`) prior to the call:
>
>
> ```
> (lldb) run
> Process 6895 launched:
> '/Volumes/Data/clang.git/llvm/Debug+Asserts/bin/clang' (x86_64)
> Process 6895 stopped
> * thread #1: tid = 0x39e920, 0x00000001010a5250
> clang`scan_dealloc_for_self_after_super_dealloc(S=0x000000010a033ce0,
> Callback=0x00007fff5fbfc410, Ctx=0x000000010a822000) + 624 at
> CheckObjCDealloc.cpp:70, queue = 'com.apple.main-thread', stop reason =
> breakpoint 1.1
>     frame #0: 0x00000001010a5250
> clang`scan_dealloc_for_self_after_super_dealloc(S=0x000000010a033ce0,
> Callback=0x00007fff5fbfc410, Ctx=0x000000010a822000) + 624 at
> CheckObjCDealloc.cpp:70
>    67         stmt(hasDescendant(declRefExpr(to(varDecl(hasName("self"))))
>    68                                .bind("self"))).bind("stmt");
>    69     Finder.addMatcher(Matcher, &Callback);
> -> 70     Finder.match(*S, Ctx);
>    71     if (Callback.FoundMatch())
>    72       return true;
>    73
> (lldb) p *S
> (clang::Stmt) $4 = {
>    = {
>     Aligner = 0x000000000000008d
>     StmtBits = (sClass = 141)
>     CompoundStmtBits = (NumStmts = 0)
>     ExprBits = {
>       ValueKind = 0
>       ObjectKind = 0
>       TypeDependent = 0
>       ValueDependent = 0
>       InstantiationDependent = 0
>       ContainsUnexpandedParameterPack = 0
>     }
>     CharacterLiteralBits = (Kind = 0)
>     FloatingLiteralBits = (Semantics = 0, IsExact = 0)
>     UnaryExprOrTypeTraitExprBits = (Kind = 0, IsType = 0)
>     DeclRefExprBits = {
>       HasQualifier = 0
>       HasTemplateKWAndArgsInfo = 0
>       HasFoundDecl = 0
>       HadMultipleCandidates = 0
>       RefersToEnclosingLocal = 0
>     }
>     CastExprBits = (Kind = 0, BasePathSize = 0)
>     CallExprBits = (NumPreArgs = 0)
>     ExprWithCleanupsBits = (NumObjects = 0)
>     PseudoObjectExprBits = (NumSubExprs = 0, ResultIndex = 0)
>     ObjCIndirectCopyRestoreExprBits = (ShouldCopy = 0)
>     InitListExprBits = (HadArrayRangeDesignator = 0)
>     TypeTraitExprBits = (Kind = 0, Value = 0, NumArgs = 0)
>   }
> }
> (lldb) p S->getStmtClassName()
> (const char *) $5 = 0x00000001044ea946 "ReturnStmt"
> (lldb) p (*S).getStmtClassName()
> (const char *) $6 = 0x00000001044ea946 "ReturnStmt"
> (lldb) s
> Process 6895 stopped
> * thread #1: tid = 0x39e920, 0x00000001010b0b7a clang`void
> clang::ast_matchers::MatchFinder::match<clang::Stmt>(this=0x00007fff5fbfbe38,
> Node=0x000000010a033ce0, Context=0x000000010a822000) + 42 at
> ASTMatchFinder.h:160, queue = 'com.apple.main-thread', stop reason = step in
>     frame #0: 0x00000001010b0b7a clang`void
> clang::ast_matchers::MatchFinder::match<clang::Stmt>(this=0x00007fff5fbfbe38,
> Node=0x000000010a033ce0, Context=0x000000010a822000) + 42 at
> ASTMatchFinder.h:160
>    157    ///
>    158    /// @{
>    159    template <typename T> void match(const T &Node, ASTContext
> &Context) {
> -> 160      match(clang::ast_type_traits::DynTypedNode::create(Node),
> Context);
>    161    }
>    162    void match(const clang::ast_type_traits::DynTypedNode &Node,
>    163               ASTContext &Context);
> (lldb) p Node.getStmtClassName()
> (const char *) $7 = 0x0000002000000000
> (lldb) p Node
> (const clang::Stmt) $8 = {
>    = {
>     Aligner = 0x000000010a033ce0
>

Is this an LLDB bug? Given that the bug was unrelated to this, it looks
like this might be an issue in LLDB's understanding of references. In
particular, it looks like it's confused as to whether 'Node' is represented
as a Stmt or as a pointer to a Stmt.


>     StmtBits = (sClass = 224)
>     CompoundStmtBits = (NumStmts = 656188)
>     ExprBits = {
>       ValueKind = 0
>       ObjectKind = 3
>       TypeDependent = 1
>       ValueDependent = 1
>       InstantiationDependent = 0
>       ContainsUnexpandedParameterPack = 0
>     }
>     CharacterLiteralBits = (Kind = 3)
>     FloatingLiteralBits = (Semantics = 3, IsExact = 0)
>     UnaryExprOrTypeTraitExprBits = (Kind = 3, IsType = 0)
>     DeclRefExprBits = {
>       HasQualifier = 1
>       HasTemplateKWAndArgsInfo = 1
>       HasFoundDecl = 0
>       HadMultipleCandidates = 0
>       RefersToEnclosingLocal = 0
>     }
>     CastExprBits = (Kind = 3, BasePathSize = 40)
>     CallExprBits = (NumPreArgs = 1)
>     ExprWithCleanupsBits = (NumObjects = 2563)
>     PseudoObjectExprBits = (NumSubExprs = 3, ResultIndex = 10)
>     ObjCIndirectCopyRestoreExprBits = (ShouldCopy = 1)
>     InitListExprBits = (HadArrayRangeDesignator = 1)
>     TypeTraitExprBits = (Kind = 3, Value = 0, NumArgs = 5)
>   }
> }
> (lldb)
> ```
>
> One thing I can't tell is if `make` is compiling with the trunk clang I'm
> building, or whether it's using the clang I have installed with Xcode.
>
> http://reviews.llvm.org/D5042
>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140824/cee0386f/attachment.html>


More information about the cfe-commits mailing list