Rule | Description | Example | KPI |
---|---|---|---|
alpha.clone.CloneChecker | Experimental: Reports similar pieces of code. | void log(); int max(int a, int b) { // warn log(); if (a > b) return a; return b; } int maxClone(int x, int y) { // similar code here log(); if (x > y) return x; return y; } | Maintainability |
alpha.core.CallAndMessageUnInitRefArg | Experimental: Check for logical errors for function calls and Objective-C message expressions (e.g., uninitialized arguments, null function pointers, and pointer to undefined variables) | void test(void) { int t; int &p = t; int &s = p; int &q = s; foo(q); // warn } | Accuracy |
alpha.core.CastSize | Experimental: Check when casting a malloc’ed type T, whether the size is a multiple of the size of T | void test() { int *x = (int *)malloc(11); // warn } | Accuracy |
alpha.core.CastToStruct | Experimental: Check for cast from non-struct pointer to struct pointer | struct s {}; void test(int *p) { struct s *ps = (struct s *) p; // warn } | Accuracy |
alpha.core.Conversion | Experimental: Loss of sign/precision in implicit conversions | void test(unsigned U, signed S) { if (S > 10) { if (U < S) { } } if (S < -10) { if (U < S) { // warn (loss of sign) } } } | Accuracy |
alpha.core.FixedAddr | Experimental: Check for assignment of a fixed address to a pointer | void test() { int *p; p = (int *) 0x10000; // warn } | Maintainability |
alpha.core.IdenticalExpr | Experimental: Warn about unintended use of identical expressions in operators | // C void test() { int a = 5; int b = a | 4 | a; // warn: identical expr on both sides } | Accuracy |
alpha.core.PointerArithm | Experimental: Check for pointer arithmetic on locations other than array elements | void test() { int x; int *p; p = &x + 1; // warn } | Maintainability |
alpha.core.PointerSub | Experimental: Check for pointer subtractions on two pointers pointing to different memory chunks | void test() { int x, y; int d = &y – &x; // warn } | Accuracy |
alpha.core.SizeofPtr | Experimental: Warn about unintended use of sizeof() on pointer expressions | struct s {}; int test(struct s *p) { return sizeof(p); // warn: sizeof(ptr) can produce an unexpected result } | Accuracy |
alpha.core.TestAfterDivZero | Experimental: Check for division by variable that is later compared against 0. Either the comparison is useless or there is division by zero. | void test(int x) { var = 77 / x; if (x == 0) { } // warn } | Robustness |
alpha.cplusplus.IteratorPastEnd | Experimental: Check iterators used past end | class A { public: A() { f(); // warn } virtual void f(); } | Robustness |
alpha.deadcode.UnreachableCode | Experimental: Check unreachable code | int test() { int x = 1; while(x); return x; // warn } | Maintainability |
alpha.security.ArrayBound | Experimental: Warn about buffer overflows (older checker) | void test() { char *s = “”; char c = s[1]; // warn } | Robustness |
alpha.security.ArrayBoundV2 | Experimental: Warn about buffer overflows | void test() { int buf[100]; int *p = buf; p = p + 99; p[1] = 1; // warn } | Robustness |
alpha.security.MallocOverflow | Experimental: Check for overflows in the arguments to malloc() | void test(int n) { void *p = malloc(n * sizeof(int)); // warn } | Robustness |
alpha.security.ReturnPtrRange | Experimental: Check for an out-of-bound pointer being returned to callers | static int A[10]; int *test() { int *p = A + 10; return p; // warn } | Robustness |
alpha.security.taint.TaintPropagation | Experimental: Generate taint information used by other checkers | void test() { char x = getchar(); // ‘x’ marked as tainted system(&x); // warn: untrusted data is passed to a system call } | Robustness |
alpha.unix.BlockInCriticalSection | Experimental: Check for calls to blocking functions inside a critical section | Robustness | |
alpha.unix.Chroot | Experimental: Check improper use of chroot | void f(); void test() { chroot(“/usr/local”); f(); // warn: no call of chdir(“/”) immediately after chroot } | Robustness |
alpha.unix.cstring.BufferOverlap | Experimental: Checks for overlap in two buffer arguments | void test() { int a[4] = {0}; memcpy(a + 2, a + 1, 8); // warn } | Maintainability |
alpha.unix.cstring.NotNullTerminated | Experimental: Check for arguments which are not null-terminating strings | void test() { int y = strlen((char *)&test); // warn } | Accuracy |
alpha.unix.cstring.OutOfBounds | Experimental: Check for out-of-bounds access in string functions | void test(char *y) { char x[4]; if (strlen(y) == 4) strncpy(x, y, 5); // warn } | Robustness |
alpha.unix.PthreadLock | Experimental: Simple lock -> unlock checker | pthread_mutex_t mtx; void test() { pthread_mutex_lock(&mtx); pthread_mutex_lock(&mtx); // warn: this lock has already been acquired } | Robustness |
alpha.unix.SimpleStream | Experimental: Check for misuses of stream APIs | void test() { FILE *F = fopen(“myfile.txt”, “w”); } // warn: opened file is never closed | Resource Utilization |
alpha.unix.Stream | Experimental: Check stream handling functions | void test() { FILE *p = fopen(“foo”, “r”); } // warn: opened file is never closed | Resource Utilization |
core.CallAndMessage | Check for logical errors for function calls and Objective-C message expressions (e.g., uninitialized arguments, null function pointers) | struct S { int x; }; void f(struct S s); void test() { struct S s; f(s); // warn: passed-by-value arg contain uninitialized data } | Accuracy |
core.UndefinedBinaryOperatorResult | Check for undefined results of binary operators | void test() { int x; int y = x + 1; // warn: left operand is garbage } | Accuracy |
core.uninitialized.Assign | Check for assigning uninitialized values | void test() { int x; x |= 1; // warn: left expression is unitialized } | Accuracy |
core.uninitialized.Branch | Check for uninitialized values used as branch conditions | void test() { int x; if (x) // warn return; } | Accuracy |
core.uninitialized.CapturedBlockVariable | Check for blocks that capture uninitialized values | void test() { int x; ^{ int y = x; }(); // warn } | Accuracy |
core.uninitialized.UndefReturn | Check for uninitialized values being returned to the caller | int test() { int x; return x; // warn } | Accuracy |
core.VLASize | Check for declarations of variable length arrays of undefined or zero size | void test() { int x; int vla1[x]; // warn: garbage as size } | Accuracy |
osx.coreFoundation.CFError | Check usage of CFErrorRef* parameters | void test(CFErrorRef *error) { // warn: function accepting CFErrorRef* should have a // non-void return } | Understandability |
osx.coreFoundation.CFNumber | Check for proper uses of CFNumber APIs | CFNumberRef test(unsigned char x) { return CFNumberCreate(0, kCFNumberSInt16Type, &x); // warn: 8 bit integer is used to initialize a 16 bit integer } | Understandability |
osx.SecKeychainAPI | Check for proper uses of Secure Keychain APIs | void test() { unsigned int *ptr = 0; UInt32 length; SecKeychainItemFreeContent(ptr, &length); // warn: trying to free data which has not been allocated } | Robustness |
security.insecureAPI.getpw | Warn on uses of the ‘getpw’ function | void test() { char buff[1024]; getpw(2, buff); // warn } | Maintainability |
security.insecureAPI.gets | Warn on uses of the ‘gets’ function | void test() { char buff[1024]; gets(buff); // warn } | Maintainability |
security.insecureAPI.mkstemp | Warn when ‘mkstemp’ is passed fewer than 6 X’s in the format string | void test() { mkstemp(“XX”); // warn } | Maintainability |
security.insecureAPI.mktemp | Warn on uses of the ‘mktemp’ function | void test() { char *x = mktemp(“/tmp/zxcv”); // warn: insecure, use mkstemp } | Maintainability |
security.insecureAPI.rand | Warn on uses of the ‘rand’, ‘random’, and related functions | void test() { random(); // warn } | Maintainability |
security.insecureAPI.strcpy | Warn on uses of the ‘strcpy’ and ‘strcat’ functions – can lead to buffer overflow. | void test() { char x[4]; char *y = “abcd”; strcpy(x, y); // warn } | Robustness |
security.insecureAPI.vfork | Warn on uses of the ‘vfork’ function | void test() { vfork(); // warn } | Maintainability |
unix.API | Check calls to various UNIX/Posix functions | // Currently the check is performed for apple targets only. void test(const char *path) { int fd = open(path, O_CREAT); // warn: call to ‘open’ requires a third argument when the // ‘O_CREAT’ flag is set } | Maintainability |
unix.cstring.BadSizeArg | Check the size argument passed into C string functions for common erroneous patterns | void test() { char dest[3]; strncat(dest, “***”, sizeof(dest)); // warn: potential buffer overflow } | Robustness |
unix.cstring.NullArg | Check for null pointers being passed as arguments to C string functions | int test() { return strlen(0); // warn } | Robustness |
unix.MallocSizeof | Check for dubious malloc arguments involving sizeof | void test() { long *p = malloc(sizeof(short)); // warn: result is converted to ‘long *’, which is // incompatible with operand type ‘short’ free(p); } | Accuracy |
unix.Vfork | Check for proper usage of vfork | int test(int x) { pid_t pid = vfork(); // warn if (pid != 0) return 0; switch (x) { case 0: pid = 1; execl(“”, “”, 0); _exit(1); break; case 1: x = 0; // warn: this assignment is prohibited break; case 2: foo(); // warn: this function call is prohibited break; default: return 0; // warn: return is prohibited } while(1); } | Maintainability |
Returning Local Address | Function should not return address of local variable because once function exits, all local variables are destroyed. This will affect robustness of code. The solution would be to dynamically allocate memory to a variable to hold the address and pass it to the function as a parameter | int* foo(int a,int b) { int sum = a + b; return ∑ /* Non-complaint */ } int* foo(int a, int b, int* sum) { *sum = a + b; return sum; /* Complaint */ } | Robustness |