diff options
author | Lenny Maiorani <lenny@colorado.edu> | 2011-03-31 22:09:14 +0000 |
---|---|---|
committer | Lenny Maiorani <lenny@colorado.edu> | 2011-03-31 22:09:14 +0000 |
commit | 5b67a82a2621c148694ff0f0352aa949b363934c (patch) | |
tree | 3501983f96dba6ffd692a6abcb398f857ead32d6 /lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp | |
parent | b8b875be7b2d177d755641c6212111859372d611 (diff) |
Add security syntax checker for strcpy() which causes the Static Analyzer to generate a warning any time the strcpy() function is used with a note suggesting to use a function which provides bounded buffers.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128679 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp b/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp index 8b1756937e..61d3e4c652 100644 --- a/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp +++ b/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp @@ -66,6 +66,7 @@ public: void CheckCall_gets(const CallExpr *CE, const FunctionDecl *FD); void CheckCall_getpw(const CallExpr *CE, const FunctionDecl *FD); void CheckCall_mktemp(const CallExpr *CE, const FunctionDecl *FD); + void CheckCall_strcpy(const CallExpr *CE, const FunctionDecl *FD); void CheckCall_rand(const CallExpr *CE, const FunctionDecl *FD); void CheckCall_random(const CallExpr *CE, const FunctionDecl *FD); void CheckUncheckedReturnValue(CallExpr *CE); @@ -98,6 +99,7 @@ void WalkAST::VisitCallExpr(CallExpr *CE) { CheckCall_gets(CE, FD); CheckCall_getpw(CE, FD); CheckCall_mktemp(CE, FD); + CheckCall_strcpy(CE, FD); if (CheckRand) { CheckCall_rand(CE, FD); CheckCall_random(CE, FD); @@ -349,6 +351,58 @@ void WalkAST::CheckCall_mktemp(const CallExpr *CE, const FunctionDecl *FD) { } //===----------------------------------------------------------------------===// +// Check: Any use of 'strcpy' is insecure. +// +// CWE-119: Improper Restriction of Operations within +// the Bounds of a Memory Buffer +//===----------------------------------------------------------------------===// +void WalkAST::CheckCall_strcpy(const CallExpr *CE, const FunctionDecl *FD) { + IdentifierInfo *II = FD->getIdentifier(); + if (!II) // if no identifier, not a simple C function + return; + llvm::StringRef Name = II->getName(); + if (Name.startswith("__builtin_")) + Name = Name.substr(10); + + if ((Name != "strcpy") && + (Name != "__strcpy_chk")) + return; + + const FunctionProtoType *FPT + = dyn_cast<FunctionProtoType>(FD->getType().IgnoreParens()); + if (!FPT) + return; + + // Verify the function takes two arguments + int numArgs = FPT->getNumArgs(); + if (numArgs != 2 && numArgs != 3) + return; + + // Verify the type for both arguments + for (int i = 0; i < 2; i++) { + // Verify that the arguments are pointers + const PointerType *PT = dyn_cast<PointerType>(FPT->getArgType(i)); + if (!PT) + return; + + // Verify that the argument is a 'char*'. + if (PT->getPointeeType().getUnqualifiedType() != BR.getContext().CharTy) + return; + } + + // Issue a warning + SourceRange R = CE->getCallee()->getSourceRange(); + BR.EmitBasicReport("Potential insecure memory buffer bounds restriction in " + "call 'strcpy'", + "Security", + "Call to function 'strcpy' is insecure as it does not " + "provide bounding of the memory buffer. Replace " + "unbounded copy functions with analogous functions that " + "support length arguments such as 'strncpy'. CWE-119.", + CE->getLocStart(), &R, 1); +} + +//===----------------------------------------------------------------------===// // Check: Linear congruent random number generators should not be used // Originally: <rdar://problem/63371000> // CWE-338: Use of cryptographically weak prng |