[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