14f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu//=== CastToStructChecker.cpp - Fixed address usage checker ----*- C++ -*--===// 24f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu// 34f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu// The LLVM Compiler Infrastructure 44f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu// 54f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu// This file is distributed under the University of Illinois Open Source 64f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu// License. See LICENSE.TXT for details. 74f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu// 84f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu//===----------------------------------------------------------------------===// 94f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu// 104f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu// This files defines CastToStructChecker, a builtin checker that checks for 11368979179c2ae4f1ff22786fc5c83c20f1cbc042Zhongxing Xu// cast from non-struct pointer to struct pointer. 124f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu// This check corresponds to CWE-588. 134f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu// 144f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu//===----------------------------------------------------------------------===// 154f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu 1623ade507cecd24b03f5e4b5ebaea48eb38060262Argyrios Kyrtzidis#include "ClangSACheckers.h" 17ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/Checker.h" 18695fb502825a53ccd178ec1c85c77929d88acb71Argyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/CheckerManager.h" 19983326f32c746f5e47161a73758e4d363263dd2cArgyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" 209b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 214f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu 224f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xuusing namespace clang; 239ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekusing namespace ento; 244f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu 254f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xunamespace { 26ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidisclass CastToStructChecker : public Checker< check::PreStmt<CastExpr> > { 276f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith mutable OwningPtr<BuiltinBug> BT; 28983326f32c746f5e47161a73758e4d363263dd2cArgyrios Kyrtzidis 294f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xupublic: 30983326f32c746f5e47161a73758e4d363263dd2cArgyrios Kyrtzidis void checkPreStmt(const CastExpr *CE, CheckerContext &C) const; 314f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu}; 324f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu} 334f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu 34983326f32c746f5e47161a73758e4d363263dd2cArgyrios Kyrtzidisvoid CastToStructChecker::checkPreStmt(const CastExpr *CE, 35983326f32c746f5e47161a73758e4d363263dd2cArgyrios Kyrtzidis CheckerContext &C) const { 364f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu const Expr *E = CE->getSubExpr(); 374f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu ASTContext &Ctx = C.getASTContext(); 384f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu QualType OrigTy = Ctx.getCanonicalType(E->getType()); 394f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu QualType ToTy = Ctx.getCanonicalType(CE->getType()); 404f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu 41f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall const PointerType *OrigPTy = dyn_cast<PointerType>(OrigTy.getTypePtr()); 42f4c7371fb1d3cebcfb40abad4537bb82515704eaJohn McCall const PointerType *ToPTy = dyn_cast<PointerType>(ToTy.getTypePtr()); 434f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu 444f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu if (!ToPTy || !OrigPTy) 454f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu return; 464f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu 474f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu QualType OrigPointeeTy = OrigPTy->getPointeeType(); 484f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu QualType ToPointeeTy = ToPTy->getPointeeType(); 494f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu 50fb87b89fc9eb103e19fb8e4b925c23f0bd091b99Douglas Gregor if (!ToPointeeTy->isStructureOrClassType()) 514f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu return; 524f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu 534f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu // We allow cast from void*. 544f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu if (OrigPointeeTy->isVoidType()) 554f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu return; 564f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu 574f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu // Now the cast-to-type is struct pointer, the original type is not void*. 584f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu if (!OrigPointeeTy->isRecordType()) { 590bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks if (ExplodedNode *N = C.addTransition()) { 604f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu if (!BT) 61983326f32c746f5e47161a73758e4d363263dd2cArgyrios Kyrtzidis BT.reset(new BuiltinBug("Cast from non-struct type to struct type", 624f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu "Casting a non-structure type to a structure type " 634f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu "and accessing a field can lead to memory access " 64983326f32c746f5e47161a73758e4d363263dd2cArgyrios Kyrtzidis "errors or data corruption.")); 65e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks BugReport *R = new BugReport(*BT,BT->getDescription(), N); 664f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu R->addRange(CE->getSourceRange()); 674f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu C.EmitReport(R); 684f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu } 694f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu } 704f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu} 714f3dc698a1bbeea16155e51dfc7d0f69ff689598Zhongxing Xu 72695fb502825a53ccd178ec1c85c77929d88acb71Argyrios Kyrtzidisvoid ento::registerCastToStructChecker(CheckerManager &mgr) { 73983326f32c746f5e47161a73758e4d363263dd2cArgyrios Kyrtzidis mgr.registerChecker<CastToStructChecker>(); 74695fb502825a53ccd178ec1c85c77929d88acb71Argyrios Kyrtzidis} 75