[cfe-commits] r86537 - in /cfe/trunk: lib/Analysis/CheckSecuritySyntaxOnly.cpp test/Analysis/security-syntax-checks.m

Zhongxing Xu xuzhongxing at gmail.com
Mon Nov 9 04:19:29 PST 2009


Author: zhongxingxu
Date: Mon Nov  9 06:19:26 2009
New Revision: 86537

URL: http://llvm.org/viewvc/llvm-project?rev=86537&view=rev
Log:
Add check for obsolete function call of getpw().

Modified:
    cfe/trunk/lib/Analysis/CheckSecuritySyntaxOnly.cpp
    cfe/trunk/test/Analysis/security-syntax-checks.m

Modified: cfe/trunk/lib/Analysis/CheckSecuritySyntaxOnly.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CheckSecuritySyntaxOnly.cpp?rev=86537&r1=86536&r2=86537&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/CheckSecuritySyntaxOnly.cpp (original)
+++ cfe/trunk/lib/Analysis/CheckSecuritySyntaxOnly.cpp Mon Nov  9 06:19:26 2009
@@ -23,6 +23,7 @@
 class VISIBILITY_HIDDEN WalkAST : public StmtVisitor<WalkAST> {
   BugReporter &BR;
   IdentifierInfo *II_gets;
+  IdentifierInfo *II_getpw;
   enum { num_rands = 9 };
   IdentifierInfo *II_rand[num_rands];
   IdentifierInfo *II_random;
@@ -31,7 +32,7 @@
 
 public:
   WalkAST(BugReporter &br) : BR(br),
-    II_gets(0), II_rand(), II_random(0), II_setid() {}
+    II_gets(0), II_getpw(0), II_rand(), II_random(0), II_setid() {}
 
   // Statement visitor methods.
   void VisitCallExpr(CallExpr *CE);
@@ -47,6 +48,7 @@
   // Checker-specific methods.
   void CheckLoopConditionForFloat(const ForStmt *FS);
   void CheckCall_gets(const CallExpr *CE, const FunctionDecl *FD);
+  void CheckCall_getpw(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);
@@ -77,6 +79,7 @@
 void WalkAST::VisitCallExpr(CallExpr *CE) {
   if (const FunctionDecl *FD = CE->getDirectCallee()) {
     CheckCall_gets(CE, FD);
+    CheckCall_getpw(CE, FD);
     CheckCall_rand(CE, FD);
     CheckCall_random(CE, FD);
   }
@@ -222,16 +225,16 @@
   if (FD->getIdentifier() != GetIdentifier(II_gets, "gets"))
     return;
 
-  const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FD->getType());
-  if (!FTP)
+  const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FD->getType());
+  if (!FPT)
     return;
 
   // Verify that the function takes a single argument.
-  if (FTP->getNumArgs() != 1)
+  if (FPT->getNumArgs() != 1)
     return;
 
   // Is the argument a 'char*'?
-  const PointerType *PT = dyn_cast<PointerType>(FTP->getArgType(0));
+  const PointerType *PT = dyn_cast<PointerType>(FPT->getArgType(0));
   if (!PT)
     return;
 
@@ -248,6 +251,44 @@
 }
 
 //===----------------------------------------------------------------------===//
+// Check: Any use of 'getpwd' is insecure.
+// CWE-477: Use of Obsolete Functions
+//===----------------------------------------------------------------------===//
+
+void WalkAST::CheckCall_getpw(const CallExpr *CE, const FunctionDecl *FD) {
+  if (FD->getIdentifier() != GetIdentifier(II_getpw, "getpw"))
+    return;
+
+  const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FD->getType());
+  if (!FPT)
+    return;
+
+  // Verify that the function takes two arguments.
+  if (FPT->getNumArgs() != 2)
+    return;
+
+  // Verify the first argument type is integer.
+  if (!FPT->getArgType(0)->isIntegerType())
+    return;
+
+  // Verify the second argument type is char*.
+  const PointerType *PT = dyn_cast<PointerType>(FPT->getArgType(1));
+  if (!PT)
+    return;
+
+  if (PT->getPointeeType().getUnqualifiedType() != BR.getContext().CharTy)
+    return;
+
+  // Issue a warning.
+  SourceRange R = CE->getCallee()->getSourceRange();
+  BR.EmitBasicReport("Potential buffer overflow in call to 'getpw'",
+                     "Security",
+                     "The getpw() function is dangerous as it may overflow the "
+                     "provided buffer. It is obsoleted by getpwuid().",
+                     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

Modified: cfe/trunk/test/Analysis/security-syntax-checks.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/security-syntax-checks.m?rev=86537&r1=86536&r2=86537&view=diff

==============================================================================
--- cfe/trunk/test/Analysis/security-syntax-checks.m (original)
+++ cfe/trunk/test/Analysis/security-syntax-checks.m Mon Nov  9 06:19:26 2009
@@ -30,6 +30,13 @@
   gets(buff); // expected-warning{{Call to function 'gets' is extremely insecure as it can always result in a buffer overflow}}
 }
 
+int getpw(unsigned int uid, char *buf);
+
+void test_getpw() {
+  char buff[1024];
+  getpw(2, buff); // expected-warning{{The getpw() function is dangerous as it may overflow the provided buffer. It is obsoleted by getpwuid().}}
+}
+
 // <rdar://problem/6337132> CWE-273: Failure to Check Whether Privileges Were
 //  Dropped Successfully
 typedef unsigned int __uint32_t;





More information about the cfe-commits mailing list