A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://clang.llvm.org/doxygen/CheckSecuritySyntaxOnly_8cpp_source.html below:

clang: lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp Source File

20#include "llvm/ADT/SmallString.h" 21#include "llvm/ADT/StringSwitch.h" 22#include "llvm/Support/raw_ostream.h" 24using namespace clang

;

29 return T

.getVendor() == llvm::Triple::Apple ||

38 bool

check_bcmp =

false

;

39 bool

check_bcopy =

false

;

40 bool

check_bzero =

false

;

41 bool

check_gets =

false

;

42 bool

check_getpw =

false

;

43 bool

check_mktemp =

false

;

44 bool

check_mkstemp =

false

;

45 bool

check_strcpy =

false

;

46 bool

check_DeprecatedOrUnsafeBufferHandling =

false

;

47 bool

check_rand =

false

;

48 bool

check_vfork =

false

;

49 bool

check_FloatLoopCounter =

false

;

50 bool

check_UncheckedReturn =

false

;

51 bool

check_decodeValueOfObjCType =

false

;

72 enum

{ num_setids = 6 };

76 const

ChecksFilter &filter;

80 const

ChecksFilter &f)

81

: BR(br), AC(ac), II_setid(),

90 void

VisitStmt(

Stmt

*S) { VisitChildren(S); }

92 void

VisitChildren(

Stmt

*S);

101 void

checkLoopConditionForFloat(

const ForStmt

*FS);

111 void

checkDeprecatedOrUnsafeBufferHandling(

const CallExpr

*CE,

117 void

checkUncheckedReturnValue(

CallExpr

*CE);

125void

WalkAST::VisitChildren(

Stmt

*S) {

126 for

(

Stmt

*Child : S->children())

131void

WalkAST::VisitCallExpr(

CallExpr

*CE) {

142

StringRef Name = II->

getName

();

143

Name.consume_front(

"__builtin_"

);

146

FnCheck evalFunction =

147

llvm::StringSwitch<FnCheck>(Name)

148

.Case(

"bcmp"

, &WalkAST::checkCall_bcmp)

149

.Case(

"bcopy"

, &WalkAST::checkCall_bcopy)

150

.Case(

"bzero"

, &WalkAST::checkCall_bzero)

151

.Case(

"gets"

, &WalkAST::checkCall_gets)

152

.Case(

"getpw"

, &WalkAST::checkCall_getpw)

153

.Case(

"mktemp"

, &WalkAST::checkCall_mktemp)

154

.Case(

"mkstemp"

, &WalkAST::checkCall_mkstemp)

155

.Case(

"mkdtemp"

, &WalkAST::checkCall_mkstemp)

156

.Case(

"mkstemps"

, &WalkAST::checkCall_mkstemp)

157

.Cases(

"strcpy"

,

"__strcpy_chk"

, &WalkAST::checkCall_strcpy)

158

.Cases(

"strcat"

,

"__strcat_chk"

, &WalkAST::checkCall_strcat)

159

.Cases(

"sprintf"

,

"vsprintf"

,

"scanf"

,

"wscanf"

,

"fscanf"

,

"fwscanf"

,

160 "vscanf"

,

"vwscanf"

,

"vfscanf"

,

"vfwscanf"

,

161

&WalkAST::checkDeprecatedOrUnsafeBufferHandling)

162

.Cases(

"sscanf"

,

"swscanf"

,

"vsscanf"

,

"vswscanf"

,

"swprintf"

,

163 "snprintf"

,

"vswprintf"

,

"vsnprintf"

,

"memcpy"

,

"memmove"

,

164

&WalkAST::checkDeprecatedOrUnsafeBufferHandling)

165

.Cases(

"strncpy"

,

"strncat"

,

"memset"

,

"fprintf"

,

166

&WalkAST::checkDeprecatedOrUnsafeBufferHandling)

167

.Case(

"drand48"

, &WalkAST::checkCall_rand)

168

.Case(

"erand48"

, &WalkAST::checkCall_rand)

169

.Case(

"jrand48"

, &WalkAST::checkCall_rand)

170

.Case(

"lrand48"

, &WalkAST::checkCall_rand)

171

.Case(

"mrand48"

, &WalkAST::checkCall_rand)

172

.Case(

"nrand48"

, &WalkAST::checkCall_rand)

173

.Case(

"lcong48"

, &WalkAST::checkCall_rand)

174

.Case(

"rand"

, &WalkAST::checkCall_rand)

175

.Case(

"rand_r"

, &WalkAST::checkCall_rand)

176

.Case(

"random"

, &WalkAST::checkCall_random)

177

.Case(

"vfork"

, &WalkAST::checkCall_vfork)

183

(this->*evalFunction)(CE, FD);

190

MsgCheck evalFunction =

192

.Case(

"decodeValueOfObjCType:at:"

,

193

&WalkAST::checkMsg_decodeValueOfObjCType)

197

(this->*evalFunction)(ME);

204 for

(

Stmt

*Child : S->children())

206 if

(

CallExpr

*CE = dyn_cast<CallExpr>(Child))

207

checkUncheckedReturnValue(CE);

212void

WalkAST::VisitForStmt(

ForStmt

*FS) {

213

checkLoopConditionForFloat(FS);

231 if

(!(B->isAssignmentOp() || B->isCompoundAssignmentOp() ||

232

B->getOpcode() == BO_Comma))

246 return

ND == x || ND == y ? DR :

nullptr

;

250 return U

->isIncrementDecrementOp()

260void

WalkAST::checkLoopConditionForFloat(

const ForStmt

*FS) {

261 if

(!filter.check_FloatLoopCounter)

265 const Expr

*condition = FS->getCond();

271 const Expr

*increment = FS->getInc();

300 if

(!drLHS && !drRHS)

303 const VarDecl

*vdLHS = drLHS ? dyn_cast<VarDecl>(drLHS->

getDecl

()) : nullptr;

304 const VarDecl

*vdRHS = drRHS ? dyn_cast<VarDecl>(drRHS->

getDecl

()) : nullptr;

306 if

(!vdLHS && !vdRHS)

315

assert(vdInc && (vdInc == vdLHS || vdInc == vdRHS));

319 const DeclRefExpr

*drCond = vdLHS == vdInc ? drLHS : drRHS;

323

llvm::raw_svector_ostream os(sbuf);

326

<<

"' with floating point type '"

<< drCond->

getType

()

327

<<

"' should not be used as a loop counter"

;

332 const char

*bugType =

"Floating point variable used as loop counter"

;

336

BR.EmitBasicReport(AC->getDecl(), filter.checkName_FloatLoopCounter,

337

bugType,

"Security"

, os.str(),

348 if

(!filter.check_bcmp)

359 for

(

int

i = 0; i < 2; i++) {

376

BR.EmitBasicReport(AC->getDecl(), filter.checkName_bcmp,

377 "Use of deprecated function in call to 'bcmp()'"

,

379 "The bcmp() function is obsoleted by memcmp()."

,

390 if

(!filter.check_bcopy)

401 for

(

int

i = 0; i < 2; i++) {

418

BR.EmitBasicReport(AC->getDecl(), filter.checkName_bcopy,

419 "Use of deprecated function in call to 'bcopy()'"

,

421 "The bcopy() function is obsoleted by memcpy() " 433 if

(!filter.check_bzero)

459

BR.EmitBasicReport(AC->getDecl(), filter.checkName_bzero,

460 "Use of deprecated function in call to 'bzero()'"

,

462 "The bzero() function is obsoleted by memset()."

,

475 if

(!filter.check_gets)

497

BR.EmitBasicReport(AC->getDecl(), filter.checkName_gets,

498 "Potential buffer overflow in call to 'gets'"

,

500 "Call to function 'gets' is extremely insecure as it can " 501 "always result in a buffer overflow"

,

511 if

(!filter.check_getpw)

537

BR.EmitBasicReport(AC->getDecl(), filter.checkName_getpw,

538 "Potential buffer overflow in call to 'getpw'"

,

540 "The getpw() function is dangerous as it may overflow the " 541 "provided buffer. It is obsoleted by getpwuid()."

,

551 if

(!filter.check_mktemp) {

554

checkCall_mkstemp(CE, FD);

578

BR.EmitBasicReport(AC->getDecl(), filter.checkName_mktemp,

579 "Potential insecure temporary file in call 'mktemp'"

,

581 "Call to function 'mktemp' is insecure as it always " 582 "creates or uses insecure temporary file. Use 'mkstemp' " 592 if

(!filter.check_mkstemp)

596

std::pair<signed, signed> ArgSuffix =

597

llvm::StringSwitch<std::pair<signed, signed> >(Name)

598

.Case(

"mktemp"

, std::make_pair(0,-1))

599

.Case(

"mkstemp"

, std::make_pair(0,-1))

600

.Case(

"mkdtemp"

, std::make_pair(0,-1))

601

.Case(

"mkstemps"

, std::make_pair(0,1))

602

.

Default

(std::make_pair(-1, -1));

604

assert(ArgSuffix.first >= 0 &&

"Unsupported function"

);

608 if

((

signed

) numArgs <= ArgSuffix.first)

612

dyn_cast<StringLiteral>(CE->

getArg

((

unsigned

)ArgSuffix.first)

624 unsigned

n = str.size();

628 if

(ArgSuffix.second >= 0) {

629 const Expr

*suffixEx = CE->

getArg

((

unsigned

)ArgSuffix.second);

633

llvm::APSInt Result = EVResult.

Val

.

getInt

();

635 if

(Result.isNegative())

637

suffix = (

unsigned

) Result.getZExtValue();

638

n = (n > suffix) ? n - suffix : 0;

641 for

(

unsigned

i = 0; i < n; ++i)

642 if

(str[i] ==

'X'

) ++numX;

651

llvm::raw_svector_ostream out(buf);

652

out <<

"Call to '"

<< Name <<

"' should have at least 6 'X's in the" 653 " format string to be secure ("

<< numX <<

" 'X'"

;

658

out <<

", "

<< suffix <<

" character"

;

661

out <<

" used as a suffix"

;

664

BR.EmitBasicReport(AC->getDecl(), filter.checkName_mkstemp,

665 "Insecure temporary file creation"

,

"Security"

,

677 if

(!filter.check_strcpy)

680 if

(!checkCall_strCommon(CE, FD))

686 if

(

const auto

*Array = dyn_cast<ConstantArrayType>(

Target

->getType())) {

687 uint64_t

ArraySize = BR.getContext().getTypeSize(Array) / 8;

688 if

(

const auto

*String = dyn_cast<StringLiteral>(Source)) {

689 if

(ArraySize >= String->getLength() + 1)

697

BR.EmitBasicReport(AC->getDecl(), filter.checkName_strcpy,

698 "Potential insecure memory buffer bounds restriction in " 701 "Call to function 'strcpy' is insecure as it does not " 702 "provide bounding of the memory buffer. Replace " 703 "unbounded copy functions with analogous functions that " 704 "support length arguments such as 'strlcpy'. CWE-119."

,

716 if

(!filter.check_strcpy)

719 if

(!checkCall_strCommon(CE, FD))

725

BR.EmitBasicReport(AC->getDecl(), filter.checkName_strcpy,

726 "Potential insecure memory buffer bounds restriction in " 729 "Call to function 'strcat' is insecure as it does not " 730 "provide bounding of the memory buffer. Replace " 731 "unbounded copy functions with analogous functions that " 732 "support length arguments such as 'strlcat'. CWE-119."

,

752void

WalkAST::checkDeprecatedOrUnsafeBufferHandling(

const CallExpr

*CE,

754 if

(!filter.check_DeprecatedOrUnsafeBufferHandling)

757 if

(!BR.getContext().getLangOpts().C11)

762 enum

{ DEPR_ONLY = -1, UNKNOWN_CALL = -2 };

765

Name.consume_front(

"__builtin_"

);

768

llvm::StringSwitch<int>(Name)

769

.Cases(

"scanf"

,

"wscanf"

,

"vscanf"

,

"vwscanf"

, 0)

770

.Cases(

"fscanf"

,

"fwscanf"

,

"vfscanf"

,

"vfwscanf"

,

"sscanf"

,

771 "swscanf"

,

"vsscanf"

,

"vswscanf"

, 1)

772

.Cases(

"sprintf"

,

"vsprintf"

,

"fprintf"

, 1)

773

.Cases(

"swprintf"

,

"snprintf"

,

"vswprintf"

,

"vsnprintf"

,

"memcpy"

,

774 "memmove"

,

"memset"

,

"strncpy"

,

"strncat"

, DEPR_ONLY)

775

.Default(UNKNOWN_CALL);

777

assert(ArgIndex != UNKNOWN_CALL &&

"Unsupported function"

);

778 bool

BoundsProvided = ArgIndex == DEPR_ONLY;

780 if

(!BoundsProvided) {

786 if

(FormatString && !FormatString->getString().contains(

"%s"

) &&

787

!FormatString->getString().contains(

"%["

))

788

BoundsProvided =

true

;

793

llvm::raw_svector_ostream Out1(Buf1);

794

llvm::raw_svector_ostream Out2(Buf2);

796

Out1 <<

"Potential insecure memory buffer bounds restriction in call '" 798

Out2 <<

"Call to function '"

<< Name

799

<<

"' is insecure as it does not provide "

;

801 if

(!BoundsProvided) {

802

Out2 <<

"bounding of the memory buffer or "

;

805

Out2 <<

"security checks introduced " 806 "in the C11 standard. Replace with analogous functions that " 807 "support length arguments or provides boundary checks such as '" 808

<< Name <<

"_s' in case of C11"

;

812

BR.EmitBasicReport(AC->getDecl(),

813

filter.checkName_DeprecatedOrUnsafeBufferHandling,

814

Out1.str(),

"Security"

, Out2.str(), CELoc,

829 if

(numArgs != 2 && numArgs != 3)

833 for

(

int

i = 0; i < 2; i++) {

859 if

(!filter.check_rand || !CheckRand)

880

llvm::raw_svector_ostream os1(buf1);

881

os1 <<

'\''

<< *FD <<

"' is a poor random number generator"

;

884

llvm::raw_svector_ostream os2(buf2);

885

os2 <<

"Function '"

<< *FD

886

<<

"' is obsolete because it implements a poor random number generator." 887

<<

" Use 'arc4random' instead"

;

891

BR.EmitBasicReport(AC->getDecl(), filter.checkName_rand, os1.str(),

892 "Security"

, os2.str(), CELoc,

898 if

(!CheckRand || !filter.check_rand)

912

BR.EmitBasicReport(AC->getDecl(), filter.checkName_rand,

913 "'random' is not a secure random number generator"

,

915 "The 'random' function produces a sequence of values that " 916 "an adversary may be able to predict. Use 'arc4random' " 926 if

(!filter.check_vfork)

932

BR.EmitBasicReport(AC->getDecl(), filter.checkName_vfork,

933 "Potential insecure implementation-specific behavior in " 936 "Call to function 'vfork' is insecure as it can lead to " 937 "denial of service situations in the parent process. " 938 "Replace calls to vfork with calls to the safer " 939 "'posix_spawn' function"

,

949void

WalkAST::checkMsg_decodeValueOfObjCType(

const ObjCMessageExpr

*ME) {

950 if

(!filter.check_decodeValueOfObjCType)

956 const TargetInfo

&TI = AC->getASTContext().getTargetInfo();

959 switch

(

T

.getOS()) {

960 case

llvm::Triple::IOS:

961 if

(VT < VersionTuple(11, 0))

964 case

llvm::Triple::MacOSX:

965 if

(VT < VersionTuple(10, 13))

968 case

llvm::Triple::WatchOS:

969 if

(VT < VersionTuple(4, 0))

972 case

llvm::Triple::TvOS:

973 if

(VT < VersionTuple(11, 0))

976 case

llvm::Triple::XROS:

985

AC->getDecl(), filter.checkName_decodeValueOfObjCType,

986 "Potential buffer overflow in '-decodeValueOfObjCType:at:'"

,

"Security"

,

987 "Deprecated method '-decodeValueOfObjCType:at:' is insecure " 988 "as it can lead to potential buffer overflows. Use the safer " 989 "'-decodeValueOfObjCType:at:size:' method."

,

1008void

WalkAST::checkUncheckedReturnValue(

CallExpr

*CE) {

1009 if

(!filter.check_UncheckedReturn)

1016 if

(II_setid[0] ==

nullptr

) {

1017 static const char

*

const

identifiers[num_setids] = {

1018 "setuid"

,

"setgid"

,

"seteuid"

,

"setegid"

,

1019 "setreuid"

,

"setregid" 1022 for

(

size_t

i = 0; i < num_setids; i++)

1023

II_setid[i] = &BR.getContext().Idents.get(identifiers[i]);

1027 size_t

identifierid;

1029 for

(identifierid = 0; identifierid < num_setids; identifierid++)

1030 if

(

id

== II_setid[identifierid])

1033 if

(identifierid >= num_setids)

1042 if

(FTP->

getNumParams

() != (identifierid < 4 ? 1 : 2))

1052

llvm::raw_svector_ostream os1(buf1);

1053

os1 <<

"Return value is not checked in call to '"

<< *FD <<

'\''

;

1056

llvm::raw_svector_ostream os2(buf2);

1057

os2 <<

"The return value from the call to '"

<< *FD

1058

<<

"' is not checked. If an error occurs in '"

<< *FD

1059

<<

"', the following code may execute with unexpected privileges"

;

1063

BR.EmitBasicReport(AC->getDecl(), filter.checkName_UncheckedReturn, os1.str(),

1064 "Security"

, os2.str(), CELoc,

1073class

SecuritySyntaxChecker :

public Checker

<check::ASTCodeBody> {

1075

ChecksFilter filter;

1089bool

ento::shouldRegisterSecuritySyntaxChecker(

const CheckerManager

&mgr) {

1093#define REGISTER_CHECKER(name) \ 1094 void ento::register##name(CheckerManager &mgr) { \ 1095 SecuritySyntaxChecker *checker = mgr.getChecker<SecuritySyntaxChecker>(); \ 1096 checker->filter.check_##name = true; \ 1097 checker->filter.checkName_##name = mgr.getCurrentCheckerName(); \ 1100 bool ento::shouldRegister##name(const CheckerManager &mgr) { return true; }

This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...

#define REGISTER_CHECKER(name)

static const DeclRefExpr * getIncrementedVar(const Expr *expr, const VarDecl *x, const VarDecl *y)

static bool isArc4RandomAvailable(const ASTContext &Ctx)

llvm::MachO::Target Target

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

const TargetInfo & getTargetInfo() const

AnalysisDeclContext contains the context data for the function, method or block under analysis.

A builtin binary operation expression such as "x + y" or "x <= y".

static bool isRelationalOp(Opcode Opc)

static bool isEqualityOp(Opcode Opc)

CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).

Expr * getArg(unsigned Arg)

getArg - Return the specified argument.

FunctionDecl * getDirectCallee()

If the callee is a FunctionDecl, return it. Otherwise return null.

unsigned getNumArgs() const

getNumArgs - Return the number of actual arguments to this call.

CompoundStmt - This represents a group of statements like { stmt stmt }.

A reference to a declared variable, function, enum, etc.

Decl - This represents one declaration (or definition), e.g.

virtual Stmt * getBody() const

getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...

This represents one expression.

bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const

EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...

Expr * IgnoreParenCasts() LLVM_READONLY

Skip past any parentheses and casts which might surround this expression until reaching a fixed point...

Expr * IgnoreParenLValueCasts() LLVM_READONLY

Skip past any parentheses and lvalue casts which might surround this expression until reaching a fixe...

Expr * IgnoreParenImpCasts() LLVM_READONLY

Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...

Expr * IgnoreImpCasts() LLVM_READONLY

Skip past any implicit casts which might surround this expression until reaching a fixed point.

ForStmt - This represents a 'for (init;cond;inc)' stmt.

Represents a function declaration or definition.

Represents a prototype with parameter type info, e.g.

unsigned getNumParams() const

QualType getParamType(unsigned i) const

One of these records is kept for each identifier that is lexed.

StringRef getName() const

Return the actual identifier string.

This represents a decl that may have a name.

IdentifierInfo * getIdentifier() const

Get the identifier that names this declaration, if there is one.

StringRef getName() const

Get the name of identifier for this declaration as a StringRef.

An expression that sends a message to the given Objective-C object or class.

Selector getSelector() const

PointerType - C99 6.7.5.1 - Pointer Declarators.

QualType getPointeeType() const

QualType getUnqualifiedType() const

Retrieve the unqualified variant of the given type, removing as little sugar as possible.

std::string getAsString() const

Derive the full selector name (e.g.

StmtVisitor - This class implements a simple visitor for Stmt subclasses.

Stmt - This represents one statement.

SourceRange getSourceRange() const LLVM_READONLY

SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...

StringLiteral - This represents a string literal expression, e.g.

StringRef getString() const

unsigned getCharByteWidth() const

Exposes information about the current target.

const llvm::Triple & getTriple() const

Returns the target triple of the primary target.

VersionTuple getPlatformMinVersion() const

Retrieve the minimum desired version of the platform, to which the program should be compiled.

bool isIntegralOrUnscopedEnumerationType() const

Determine whether this type is an integral or unscoped enumeration type.

bool isRealFloatingType() const

Floating point categories.

const T * getAs() const

Member-template getAs<specific type>'.

UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...

Represents a variable declaration or definition.

AnalysisDeclContext * getAnalysisDeclContext(const Decl *D)

BugReporter is a utility class for generating PathDiagnostics for analysis.

CHECKER * registerChecker(AT &&... Args)

Used to register checkers.

This wrapper is used to ensure that only StringRefs originating from the CheckerRegistry are used as ...

static PathDiagnosticLocation createBegin(const Decl *D, const SourceManager &SM)

Create a location for the beginning of the declaration.

Defines the clang::TargetInfo interface.

const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr

Matches expressions.

The JSON file list parser is used to communicate input to InstallAPI.

const FunctionProtoType * T

EvalResult is a struct with detailed info about an evaluated expression.

APValue Val

Val - This is the value the expression can be folded to.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4