Implement: <rdar://problem/6337132> CWE-273: Failure to Check Whether Privileges
                                    Were Dropped Successfully

Patch by Geoff Keating!


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80313 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Analysis/security-syntax-checks.m b/test/Analysis/security-syntax-checks.m
index 7e2a03d..df17926 100644
--- a/test/Analysis/security-syntax-checks.m
+++ b/test/Analysis/security-syntax-checks.m
@@ -1,4 +1,4 @@
-// RUN: clang-cc -analyze -warn-security-syntactic %s -verify
+// RUN: clang-cc -triple i386-apple-darwin10 -analyze -warn-security-syntactic %s -verify
 
 // <rdar://problem/6336718> rule request: floating point used as loop 
 //  condition (FLP30-C, FLP-30-CPP)
@@ -29,3 +29,34 @@
   char buff[1024];
   gets(buff); // expected-warning{{Call to function 'gets' is extremely insecure as it can always result in a buffer overflow}}
 }
+
+// <rdar://problem/6337132> CWE-273: Failure to Check Whether Privileges Were
+//  Dropped Successfully
+typedef unsigned int __uint32_t;
+typedef __uint32_t __darwin_uid_t;
+typedef __uint32_t __darwin_gid_t;
+typedef __darwin_uid_t uid_t;
+typedef __darwin_gid_t gid_t;
+int setuid(uid_t);
+int setregid(gid_t, gid_t);
+int setreuid(uid_t, uid_t);
+extern void check(int);
+
+void test_setuid() 
+{
+  setuid(2); // expected-warning{{The return value from the call to 'setuid' is not checked.  If an error occurs in 'setuid', the following code may execute with unexpected privileges}}
+  setuid(0); // expected-warning{{The return value from the call to 'setuid' is not checked.  If an error occurs in 'setuid', the following code may execute with unexpected privileges}}
+  if (setuid (2) != 0)
+    abort();
+
+  // Currently the 'setuid' check is not flow-sensitive, and only looks
+  // at whether the function was called in a compound statement.  This
+  // will lead to false negatives, but there should be no false positives.
+  int t = setuid(2);  // no-warning
+  (void)setuid (2); // no-warning
+
+  check(setuid (2)); // no-warning
+
+  setreuid(2,2); // expected-warning{{The return value from the call to 'setreuid' is not checked.  If an error occurs in 'setreuid', the following code may execute with unexpected privileges}}
+  setregid(2,2); // expected-warning{{The return value from the call to 'setregid' is not checked.  If an error occurs in 'setregid', the following code may execute with unexpected privileges}}
+}