1b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu//=== FixedAddressChecker.cpp - Fixed address usage checker ----*- C++ -*--===// 2b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu// 3b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu// The LLVM Compiler Infrastructure 4b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu// 5b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu// This file is distributed under the University of Illinois Open Source 6b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu// License. See LICENSE.TXT for details. 7b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu// 8b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu//===----------------------------------------------------------------------===// 9b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu// 10b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu// This files defines FixedAddressChecker, a builtin checker that checks for 11b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu// assignment of a fixed address to a pointer. 12b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu// This check corresponds to CWE-587. 13b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu// 14b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu//===----------------------------------------------------------------------===// 15b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu 1623ade507cecd24b03f5e4b5ebaea48eb38060262Argyrios Kyrtzidis#include "ClangSACheckers.h" 1755fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" 18ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/Checker.h" 19695fb502825a53ccd178ec1c85c77929d88acb71Argyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/CheckerManager.h" 20983326f32c746f5e47161a73758e4d363263dd2cArgyrios Kyrtzidis#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" 21b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu 22b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xuusing namespace clang; 239ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekusing namespace ento; 24b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu 25b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xunamespace { 2687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarclass FixedAddressChecker 27ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidis : public Checker< check::PreStmt<BinaryOperator> > { 28651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines mutable std::unique_ptr<BuiltinBug> BT; 29983326f32c746f5e47161a73758e4d363263dd2cArgyrios Kyrtzidis 30b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xupublic: 31983326f32c746f5e47161a73758e4d363263dd2cArgyrios Kyrtzidis void checkPreStmt(const BinaryOperator *B, CheckerContext &C) const; 32b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu}; 33b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu} 34b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu 35983326f32c746f5e47161a73758e4d363263dd2cArgyrios Kyrtzidisvoid FixedAddressChecker::checkPreStmt(const BinaryOperator *B, 36983326f32c746f5e47161a73758e4d363263dd2cArgyrios Kyrtzidis CheckerContext &C) const { 37b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu // Using a fixed address is not portable because that address will probably 38b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu // not be valid in all environments or platforms. 39b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu 402de56d1d0c3a504ad1529de2677628bdfbb95cd4John McCall if (B->getOpcode() != BO_Assign) 41b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu return; 42b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu 43b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu QualType T = B->getType(); 44b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu if (!T->isPointerType()) 45b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu return; 46b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu 478bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek ProgramStateRef state = C.getState(); 485eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek SVal RV = state->getSVal(B->getRHS(), C.getLocationContext()); 49b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu 50b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu if (!RV.isConstant() || RV.isZeroConstant()) 51b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu return; 52b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu 5387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (ExplodedNode *N = C.generateNonFatalErrorNode()) { 54b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu if (!BT) 55651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BT.reset( 56651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines new BuiltinBug(this, "Use fixed address", 57651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "Using a fixed address is not portable because that " 58651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "address will probably not be valid in all " 59651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines "environments or platforms.")); 6087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar auto R = llvm::make_unique<BugReport>(*BT, BT->getDescription(), N); 61b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu R->addRange(B->getRHS()->getSourceRange()); 6287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar C.emitReport(std::move(R)); 63b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu } 64b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu} 65b10a7c235f82c6eb074be097c9ae7ee51fccc9c6Zhongxing Xu 66695fb502825a53ccd178ec1c85c77929d88acb71Argyrios Kyrtzidisvoid ento::registerFixedAddressChecker(CheckerManager &mgr) { 67983326f32c746f5e47161a73758e4d363263dd2cArgyrios Kyrtzidis mgr.registerChecker<FixedAddressChecker>(); 68695fb502825a53ccd178ec1c85c77929d88acb71Argyrios Kyrtzidis} 69