]> granicus.if.org Git - clang/commitdiff
[analyzer] Don't flag strcpy of string literals into sufficiently large buffers.
authorArtem Dergachev <artem.dergachev@gmail.com>
Fri, 12 Jan 2018 22:12:11 +0000 (22:12 +0000)
committerArtem Dergachev <artem.dergachev@gmail.com>
Fri, 12 Jan 2018 22:12:11 +0000 (22:12 +0000)
In the security package, we have a simple syntactic check that warns about
strcpy() being insecure, due to potential buffer overflows.

Suppress that check's warning in the trivial situation when the source is an
immediate null-terminated string literal and the target is an immediate
sufficiently large buffer.

Patch by AndrĂ¡s Leitereg!

Differential Revision: https://reviews.llvm.org/D41384

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@322410 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
test/Analysis/security-syntax-checks.m

index 6dbacad7f2eab8476326e37168a25bb35b1d6961..62831be26eb2e6f8fe00def292e18b2d3ba8d9a4 100644 (file)
@@ -510,6 +510,17 @@ void WalkAST::checkCall_strcpy(const CallExpr *CE, const FunctionDecl *FD) {
   if (!checkCall_strCommon(CE, FD))
     return;
 
+  const auto *Target = CE->getArg(0)->IgnoreImpCasts(),
+             *Source = CE->getArg(1)->IgnoreImpCasts();
+  if (const auto *DeclRef = dyn_cast<DeclRefExpr>(Target))
+    if (const auto *Array = dyn_cast<ConstantArrayType>(DeclRef->getType())) {
+      uint64_t ArraySize = BR.getContext().getTypeSize(Array) / 8;
+      if (const auto *String = dyn_cast<StringLiteral>(Source)) {
+        if (ArraySize >= String->getLength() + 1)
+          return;
+      }
+    }
+
   // Issue a warning.
   PathDiagnosticLocation CELoc =
     PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
index 04a4c7d8665530396bff071481a856849f8e902b..8560ba29e70222614eb1893471efed376ce1e2d9 100644 (file)
@@ -146,6 +146,16 @@ void test_strcpy() {
   strcpy(x, y); //expected-warning{{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 'strlcpy'. CWE-119}}
 }
 
+void test_strcpy_2() {
+  char x[4];
+  strcpy(x, "abcd"); //expected-warning{{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 'strlcpy'. CWE-119}}
+}
+
+void test_strcpy_safe() {
+  char x[5];
+  strcpy(x, "abcd");
+}
+
 //===----------------------------------------------------------------------===
 // strcat()
 //===----------------------------------------------------------------------===