[PATCH] D127105: [analyzer] Fix null pointer deref in CastValueChecker
Vince Bridgers via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon Jun 6 05:39:03 PDT 2022
vabridgers created this revision.
vabridgers added reviewers: martong, steakhal, NoQ.
Herald added subscribers: manas, ASDenysPetrov, dkrupp, donat.nagy, Szelethus, mikhail.ramalho, a.sidorin, rnkovacs, szepet, baloghadamsoftware, xazax.hun.
Herald added a project: All.
vabridgers requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
A crash was seen in CastValueChecker due to a null pointer dereference
when analyzing proprietary source code. A suitably small and obfuscated
reproducer cannot be provided at this time, but a description of the
problem seen can be provided. The crash seen is as follows, with debug
information dump following.
The fix seeks to simply avoid the null pointer dereference, thus
preventing the crash.
Program received signal SIGSEGV, Segmentation fault.
0x0000000009c2d380 in clang::DeclarationName::getAsString[abi:cxx11]()
const (this=0x28)
at ../../clang/lib/AST/DeclarationName.cpp:238
238 OS << *this;
(gdb) bt
clang::DeclarationName::getAsString[abi:cxx11]() const (this=0x28)
at ../../clang/lib/AST/DeclarationName.cpp:238
const (this=0x0)
at ../../clang/include/clang/AST/Decl.h:290
Object=0x1c11af18,
CastSucceeds=true, IsKnownCast=false)
at ../../clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp:111
State=..., C=..., IsInstanceOf=true)
at ../../clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp:319
namespace)::CastValueChecker::evalIsa (this=0x10cdf140, Call=...,
DV=..., C=...) at
../../clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp:437
...
(gdb) frame 2
Object=0x1c11af18,
CastSucceeds=true, IsKnownCast=false)
at ../../clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp:111
111 :
CastToTy->getPointeeCXXRecordDecl()->getNameAsString();
(gdb) p CastToTy
$1 = {Value = {Value = 312725088}}
(gdb) p CastToTy->getPointeeCXXRecordDecl()
$2 = (const clang::CXXRecordDecl *) 0x0
(gdb) p CastToTy.dump()
LValueReferenceType 0x12a3ce60 'class llvm::ReplaceableMetadataImpl *&'
`-PointerType 0x129971b0 'class llvm::ReplaceableMetadataImpl *'
`-RecordType 0x128afce0 'class llvm::ReplaceableMetadataImpl'
`-CXXRecord 0x128ff160 'ReplaceableMetadataImpl'
(gdb) frame 16
(this=0x7fffffff9208, currStmt=0x1f026978, Pred=0x22cf76f0)
at ../../clang/lib/StaticAnalyzer/Core/ExprEngine.cpp:783
783 Visit(currStmt, I, DstI);
(gdb) p currStmt
$1 = (const clang::Stmt *) 0x1f026978
(gdb) p currStmt->dump()
CallExpr 0x1f026978 '_Bool'
| -ImplicitCastExpr 0x1f026960 '_Bool (*)(const class |
|
llvm::PointerUnion<const class clang::Type *, const class
clang::ExtQuals *> &)' <FunctionToPointerDecay>
| `-DeclRefExpr 0x1f026908 '_Bool (const class llvm::PointerUnion<const |
|
class clang::Type *, const class clang::ExtQuals *> &)' lvalue Function
0x1f007e58 'isa' '_Bool (const class llvm::PointerUnion<const class
clang::Type *, const class clang::ExtQuals *> &)' (FunctionTemplate
0x11c5df38 'isa')
`-UnaryOperator 0x1f026738 'const class llvm::PointerUnion<const class
clang::Type *, const class clang::ExtQuals *>' lvalue prefix '*' cannot
overflow
`-CXXThisExpr 0x1f026728 'const class llvm::PointerUnion<const class
clang::Type *, const class clang::ExtQuals *> *' this
$2 = void
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D127105
Files:
clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp
Index: clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp
@@ -108,7 +108,9 @@
bool CastSucceeds, bool IsKnownCast) {
std::string CastToName =
CastInfo ? CastInfo->to()->getAsCXXRecordDecl()->getNameAsString()
- : CastToTy->getPointeeCXXRecordDecl()->getNameAsString();
+ : (CastToTy->getPointeeCXXRecordDecl() != nullptr)
+ ? CastToTy->getPointeeCXXRecordDecl()->getNameAsString()
+ : "(nil)";
Object = Object->IgnoreParenImpCasts();
return C.getNoteTag(
@@ -163,9 +165,11 @@
bool First = true;
for (QualType CastToTy: CastToTyVec) {
std::string CastToName =
- CastToTy->getAsCXXRecordDecl() ?
- CastToTy->getAsCXXRecordDecl()->getNameAsString() :
- CastToTy->getPointeeCXXRecordDecl()->getNameAsString();
+ CastToTy->getAsCXXRecordDecl()
+ ? CastToTy->getAsCXXRecordDecl()->getNameAsString()
+ : (CastToTy->getPointeeCXXRecordDecl() != nullptr)
+ ? CastToTy->getPointeeCXXRecordDecl()->getNameAsString()
+ : "(nil)";
Out << ' ' << ((CastToTyVec.size() == 1) ? "not" :
(First ? "neither" : "nor")) << " a '" << CastToName
<< '\'';
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D127105.434444.patch
Type: text/x-patch
Size: 1501 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220606/7c7f8433/attachment-0001.bin>
More information about the cfe-commits
mailing list